예제 #1
0
        public override async Task DoReceiveMessageAsync()
        {
            // receive bytes
            UdpReceiveResult udpRes;

            try
            {
                udpRes = await _udpClient.ReceiveAsync().WithCancellation(CloseToken);
            }
            catch (OperationCanceledException)
            {
                // the socket has been closed
                return;
            }

            var buf = AlternativeCompositeByteBuf.CompBuffer();

            buf.WriteBytes(udpRes.Buffer.ToSByteArray());

            var localEp = (IPEndPoint)Socket.LocalEndPoint;

            RemoteEndPoint = udpRes.RemoteEndPoint;

            var dgram = new DatagramPacket(buf, localEp, RemoteEndPoint);

            Logger.Debug("Received {0}. {1} : {2}", dgram, Convenient.ToHumanReadable(udpRes.Buffer.Length), Convenient.ToString(udpRes.Buffer));

            // execute inbound pipeline
            if (Session.IsTimedOut)
            {
                return;
            }
            Session.Read(dgram);
            Session.Reset();
        }
예제 #2
0
        private static Buffer CreateTestBuffer()
        {
            var acbb = AlternativeCompositeByteBuf.CompBuffer();

            acbb.WriteBytes(TestRawBytes);
            return(new Buffer(acbb));
        }
예제 #3
0
        public static sbyte[] ReadJavaBytes(byte[] bytes)
        {
            AlternativeCompositeByteBuf buf = AlternativeCompositeByteBuf.CompBuffer();

            buf.WriteBytes(bytes.ToSByteArray());
            return(ExtractBytes(buf).ToSByteArray());
        }
예제 #4
0
        /// <summary>
        /// Encodes a provided message into a byte array.
        /// </summary>
        /// <param name="message">The message to be encoded.</param>
        /// <returns>The encoded message as byte array.</returns>
        public static byte[] EncodeMessage(Message message)
        {
            var encoder = new Encoder(null);
            AlternativeCompositeByteBuf buf = AlternativeCompositeByteBuf.CompBuffer();

            encoder.Write(buf, message, null);

            return(InteropUtil.ExtractBytes(buf));
        }
예제 #5
0
            public Buffer Reply(PeerAddress sender, Buffer requestBuffer, bool complete)
            {
                int i = requestBuffer.BackingBuffer.ReadInt();

                Console.WriteLine("Got {0}.", i);
                var buffer = AlternativeCompositeByteBuf.CompBuffer().WriteInt(i);

                return(new Buffer(buffer));
            }
예제 #6
0
        public async void TestOrder()
        {
            Peer           sender = null;
            Peer           recv1  = null;
            ChannelCreator cc     = null;

            try
            {
                sender = new PeerBuilder(new Number160("0x50"))
                         .SetMaintenanceTask(Utils2.CreateInfiniteIntervalMaintenanceTask())
                         .SetChannelServerConfiguration(Utils2.CreateInfiniteTimeoutChannelServerConfiguration(2525, 2525))
                         .SetP2PId(55)
                         .SetPorts(2525)
                         .Start();
                recv1 = new PeerBuilder(new Number160("0x20"))
                        .SetMaintenanceTask(Utils2.CreateInfiniteIntervalMaintenanceTask())
                        .SetChannelServerConfiguration(Utils2.CreateInfiniteTimeoutChannelServerConfiguration(9099, 9099))
                        .SetP2PId(55)
                        .SetPorts(8088)
                        .Start();
                recv1.RawDataReply(new TestOrderRawDataReply());

                for (int i = 0; i < 500; i++)
                {
                    cc = await sender.ConnectionBean.Reservation.CreateAsync(0, 1);

                    var sendDirectBuilder = new SendDirectBuilder(sender, (PeerAddress)null);
                    var buffer            = AlternativeCompositeByteBuf.CompBuffer().WriteInt(i);
                    sendDirectBuilder.SetBuffer(new Buffer(buffer));
                    sendDirectBuilder.SetIsStreaming();

                    var tr = sender.DirectDataRpc.SendAsync(recv1.PeerAddress, sendDirectBuilder, cc);
                    Core.Utils.Utils.AddReleaseListener(cc, tr);
                    tr.ContinueWith(t =>
                    {
                        int j = t.Result.Buffer(0).BackingBuffer.ReadInt();
                        Console.WriteLine("Received {0}.", j);
                    });
                }
            }
            finally
            {
                if (sender != null)
                {
                    sender.ShutdownAsync().Wait();
                }
                if (recv1 != null)
                {
                    recv1.ShutdownAsync().Wait();
                }
                if (cc != null)
                {
                    cc.ShutdownAsync().Wait();
                }
            }
        }
예제 #7
0
        protected static Buffer CreateSampleBuffer()
        {
            var acbb = AlternativeCompositeByteBuf.CompBuffer();

            for (int i = 0; i < BufferSizeBytes; i++)
            {
                acbb.WriteByte(i % 256);
            }
            return(new Buffer(acbb));
        }
예제 #8
0
        protected override async Task ProcessRequestAsync(object state)
        {
            var udpRes = (UdpReceiveResult)state;

            // prepare new session
            var buf     = AlternativeCompositeByteBuf.CompBuffer();
            var session = Pipeline.CreateNewServerSession(this);

            session.TriggerActive();

            // process content
            buf.WriteBytes(udpRes.Buffer.ToSByteArray());

            var localEp  = (IPEndPoint)_udpClient.Client.LocalEndPoint;
            var remoteEp = udpRes.RemoteEndPoint;

            var dgram = new DatagramPacket(buf, localEp, remoteEp);

            Logger.Debug("Received {0}. {1} : {2}", dgram, Convenient.ToHumanReadable(udpRes.Buffer.Length),
                         Convenient.ToString(udpRes.Buffer));

            // execute inbound pipeline
            var readRes = session.Read(dgram); // resets timeout

            if (session.IsTimedOut)
            {
                session.TriggerInactive();
                return;
            }

            // execute outbound pipeline
            var writeRes = session.Write(readRes); // resets timeout

            if (session.IsTimedOut)
            {
                session.TriggerInactive();
                return;
            }

            // send back
            var bytes = ConnectionHelper.ExtractBytes(writeRes);
            await _udpClient.SendAsync(bytes, bytes.Length, remoteEp);

            NotifyWriteCompleted(); // resets timeout
            Logger.Debug("Sent {0} : {1}", Convenient.ToHumanReadable(udpRes.Buffer.Length),
                         Convenient.ToString(udpRes.Buffer));

            session.TriggerInactive();
        }
예제 #9
0
        public void TestDecodeByte()
        {
            var bytes = JarRunner.RequestJavaBytes();

            var buf = AlternativeCompositeByteBuf.CompBuffer();

            buf.WriteBytes(bytes.ToSByteArray());

            // Java byte is signed
            for (int i = sbyte.MinValue; i <= sbyte.MaxValue; i++) // -128 ... 127
            {
                sbyte b = buf.ReadByte();
                Assert.IsTrue(i == b);
            }
        }
예제 #10
0
        public void TestEncodeByte()
        {
            var buffer = AlternativeCompositeByteBuf.CompBuffer();

            // Java byte is signed
            for (int i = sbyte.MinValue; i <= sbyte.MaxValue; i++) // -128 ... 127
            {
                buffer.WriteByte((sbyte)i);
            }

            var bytes = InteropUtil.ExtractBytes(buffer);

            bool interopResult = JarRunner.WriteBytesAndTestInterop(bytes);

            Assert.IsTrue(interopResult);
        }
예제 #11
0
        public override void Read(ChannelHandlerContext ctx, object msg)
        {
            // .NET-specific: use a content wrapper for TCP, similar to TomP2PSinglePacketUdp
            var piece = msg as StreamPiece;

            if (piece == null)
            {
                //ctx.FireRead(msg);
                return;
            }

            var buf       = piece.Content;
            var sender    = piece.Sender;
            var recipient = piece.Recipient;

            Logger.Debug("{0}: Cumulating TCP stream piece.", this);
            try
            {
                if (_cumulation == null)
                {
                    _cumulation = AlternativeCompositeByteBuf.CompBuffer(buf);
                }
                else
                {
                    // add to overhead from last TCP packet
                    _cumulation.AddComponent(buf);
                }
                Decoding(ctx, sender, recipient);
            }
            catch (Exception)
            {
                Logger.Error("Error in TCP decoding.");
                throw;
            }
            finally
            {
                // If the currently read buffer is read, it can be deallocated.
                // In case another TCP packet follows, a new buffer is created.
                if (_cumulation != null && !_cumulation.IsReadable)
                {
                    _cumulation = null;
                    // Java: no need to discard bytes as this was done in the decoder already
                }
            }
        }
예제 #12
0
        public void TestDecodeBytes()
        {
            var bytes = JarRunner.RequestJavaBytes();

            var buf = AlternativeCompositeByteBuf.CompBuffer();

            buf.WriteBytes(bytes.ToSByteArray());

            // Java byte is signed
            var byteArray = new sbyte[256];

            buf.ReadBytes(byteArray);

            for (int i = 0, b = sbyte.MinValue; i <= sbyte.MaxValue; i++, b++) // -128 ... 127
            {
                Assert.IsTrue(b == byteArray[i]);
            }
        }
예제 #13
0
        public void TestEncodeBytes()
        {
            AlternativeCompositeByteBuf buffer = AlternativeCompositeByteBuf.CompBuffer();

            // Java byte is signed
            sbyte[] byteArray = new sbyte[256];
            for (int i = 0, b = sbyte.MinValue; b <= sbyte.MaxValue; i++, b++) // -128 ... 127
            {
                byteArray[i] = (sbyte)b;
            }

            buffer.WriteBytes(byteArray);

            var bytes = InteropUtil.ExtractBytes(buffer);

            bool interopResult = JarRunner.WriteBytesAndTestInterop(bytes);

            Assert.IsTrue(interopResult);
        }
예제 #14
0
        /// <summary>
        /// Decodes a message from the provided byte array.
        /// </summary>
        /// <param name="bytes">The message bytes from Java encoding.</param>
        /// <returns>The .NET message version.</returns>
        public static Message DecodeMessage(byte[] bytes)
        {
            var decoder = new Decoder(null);

            // mock a non-working ChannelHandlerContext
            var pipeline = new Pipeline();
            var channel  = new MyTcpClient(new IPEndPoint(IPAddress.Any, 0), pipeline);
            var session  = new PipelineSession(channel, pipeline, new List <IInboundHandler>(), new List <IOutboundHandler>());
            var ctx      = new ChannelHandlerContext(channel, session);

            // create dummy sender for decoding
            var message = Utils2.CreateDummyMessage();
            AlternativeCompositeByteBuf buf = AlternativeCompositeByteBuf.CompBuffer();

            buf.WriteBytes(bytes.ToSByteArray());
            decoder.Decode(ctx, buf, message.Recipient.CreateSocketTcp(), message.Sender.CreateSocketTcp());

            return(decoder.Message);
        }
예제 #15
0
        public override async Task DoReceiveMessageAsync()
        {
            // TODO find zero-copy way, use same buffer
            // receive bytes
            var bytesRecv = new byte[256];
            var buf       = AlternativeCompositeByteBuf.CompBuffer();

            var stream     = _tcpClient.GetStream();
            var pieceCount = 0;

            do
            {
                Array.Clear(bytesRecv, 0, bytesRecv.Length);
                buf.Clear();
                int nrBytes;
                try
                {
                    nrBytes = await stream.ReadAsync(bytesRecv, 0, bytesRecv.Length).WithCancellation(CloseToken);
                }
                catch (OperationCanceledException)
                {
                    // the socket has been closed
                    return;
                }
                buf.WriteBytes(bytesRecv.ToSByteArray(), 0, nrBytes);

                var localEp = (IPEndPoint)Socket.LocalEndPoint;
                RemoteEndPoint = (IPEndPoint)Socket.RemoteEndPoint;

                var piece = new StreamPiece(buf, localEp, RemoteEndPoint);
                Logger.Debug("[{0}] Received {1}. {2} : {3}", ++pieceCount, piece, Convenient.ToHumanReadable(nrBytes), Convenient.ToString(bytesRecv));

                // execute inbound pipeline, per piece (reset session!)
                if (Session.IsTimedOut)
                {
                    return;
                }
                Session.Read(piece);
                Session.Reset();
            } while (!IsClosed && stream.DataAvailable && !Session.IsTimedOut);
        }
예제 #16
0
        private static Message CreateMessageByteBuffer()
        {
            // write some random bytes
            var buf = AlternativeCompositeByteBuf.CompBuffer();

            for (int i = 0; i < 300; i++)
            {
                switch (i % 3)
                {
                case 0:
                    buf.WriteBytes(_sampleBytes1);
                    break;

                case 1:
                    buf.WriteBytes(_sampleBytes2);
                    break;

                case 2:
                    buf.WriteBytes(_sampleBytes3);
                    break;
                }
            }

            // decompose buffer and use the resulting 8 ByteBufs in the list
            var decoms = buf.Decompose(0, buf.ReadableBytes);

            var m = Utils2.CreateDummyMessage();

            m.SetBuffer(new Buffer(decoms[0]));
            m.SetBuffer(new Buffer(decoms[1]));
            m.SetBuffer(new Buffer(decoms[2]));
            m.SetBuffer(new Buffer(decoms[3]));
            m.SetBuffer(new Buffer(decoms[4]));
            m.SetBuffer(new Buffer(decoms[5]));
            m.SetBuffer(new Buffer(decoms[6]));
            m.SetBuffer(new Buffer(decoms[7]));
            return(m);
        }
예제 #17
0
        public void TestEncodeInt()
        {
            AlternativeCompositeByteBuf buffer = AlternativeCompositeByteBuf.CompBuffer();

            buffer.WriteInt(int.MinValue);  //-2147483648
            buffer.WriteInt(-256);
            buffer.WriteInt(-255);
            buffer.WriteInt(-128);
            buffer.WriteInt(-127);
            buffer.WriteInt(-1);
            buffer.WriteInt(0);
            buffer.WriteInt(1);
            buffer.WriteInt(127);
            buffer.WriteInt(128);
            buffer.WriteInt(255);
            buffer.WriteInt(256);
            buffer.WriteInt(int.MaxValue);  // 2147483647

            var bytes = InteropUtil.ExtractBytes(buffer);

            bool interopResult = JarRunner.WriteBytesAndTestInterop(bytes);

            Assert.IsTrue(interopResult);
        }
예제 #18
0
        public void TestEncodeLong()
        {
            AlternativeCompositeByteBuf buffer = AlternativeCompositeByteBuf.CompBuffer();

            buffer.WriteLong(long.MinValue);  //-923372036854775808
            buffer.WriteLong(-256);
            buffer.WriteLong(-255);
            buffer.WriteLong(-128);
            buffer.WriteLong(-127);
            buffer.WriteLong(-1);
            buffer.WriteLong(0);
            buffer.WriteLong(1);
            buffer.WriteLong(127);
            buffer.WriteLong(128);
            buffer.WriteLong(255);
            buffer.WriteLong(256);
            buffer.WriteLong(long.MaxValue);  // 923372036854775807

            var bytes = InteropUtil.ExtractBytes(buffer);

            bool interopResult = JarRunner.WriteBytesAndTestInterop(bytes);

            Assert.IsTrue(interopResult);
        }
예제 #19
0
        public void TestDecodeLong()
        {
            var bytes = JarRunner.RequestJavaBytes();

            var buf = AlternativeCompositeByteBuf.CompBuffer();

            buf.WriteBytes(bytes.ToSByteArray());

            long val1  = buf.ReadLong();
            long val2  = buf.ReadLong();
            long val3  = buf.ReadLong();
            long val4  = buf.ReadLong();
            long val5  = buf.ReadLong();
            long val6  = buf.ReadLong();
            long val7  = buf.ReadLong();
            long val8  = buf.ReadLong();
            long val9  = buf.ReadLong();
            long val10 = buf.ReadLong();
            long val11 = buf.ReadLong();
            long val12 = buf.ReadLong();
            long val13 = buf.ReadLong();

            Assert.IsTrue(val1 == long.MinValue);
            Assert.IsTrue(val2 == -256);
            Assert.IsTrue(val3 == -255);
            Assert.IsTrue(val4 == -128);
            Assert.IsTrue(val5 == -127);
            Assert.IsTrue(val6 == -1);
            Assert.IsTrue(val7 == 0);
            Assert.IsTrue(val8 == 1);
            Assert.IsTrue(val9 == 127);
            Assert.IsTrue(val10 == 128);
            Assert.IsTrue(val11 == 255);
            Assert.IsTrue(val12 == 256);
            Assert.IsTrue(val13 == long.MaxValue);
        }
예제 #20
0
        protected override async Task ProcessRequestAsync(object state)
        {
            var client = (TcpClient)state;
            var stream = client.GetStream();

            object readRes;
            var    pieceCount = 0;

            // prepare new session
            var recvBuffer = new byte[256];
            var buf        = AlternativeCompositeByteBuf.CompBuffer();
            var session    = Pipeline.CreateNewServerSession(this);

            session.TriggerActive();

            // process content
            do
            {
                // TODO find zero-copy way, use same buffer
                Array.Clear(recvBuffer, 0, recvBuffer.Length);
                buf.Clear();
                var nrBytes = await stream.ReadAsync(recvBuffer, 0, recvBuffer.Length);

                buf.WriteBytes(recvBuffer.ToSByteArray(), 0, nrBytes);

                var localEp  = (IPEndPoint)client.Client.LocalEndPoint;
                var remoteEp = (IPEndPoint)client.Client.RemoteEndPoint;

                var piece = new StreamPiece(buf, localEp, remoteEp);
                Logger.Debug("[{0}] Received {1}. {2} : {3}", ++pieceCount, piece,
                             Convenient.ToHumanReadable(nrBytes), Convenient.ToString(recvBuffer));

                // execute inbound pipeline, per piece
                readRes = session.Read(piece); // resets timeout
                session.Reset();               // resets session internals
            } while (!IsClosed && stream.DataAvailable && !session.IsTimedOut);

            if (session.IsTimedOut)
            {
                session.TriggerInactive();
                return;
            }

            // execute outbound pipeline
            var writeRes = session.Write(readRes); // resets timeout

            if (session.IsTimedOut)
            {
                session.TriggerInactive();
                return;
            }

            // send back
            var bytes = ConnectionHelper.ExtractBytes(writeRes);
            await stream.WriteAsync(bytes, 0, bytes.Length);

            NotifyWriteCompleted(); // resets timeout
            Logger.Debug("Sent {0} : {1}", Convenient.ToHumanReadable(bytes.Length), Convenient.ToString(bytes));

            session.TriggerInactive();
        }
예제 #21
0
 public AlternativeCompositeByteBuf CompBuffer()
 {
     return(AlternativeCompositeByteBuf.CompBuffer());
 }
예제 #22
0
        private bool DecodePayload(AlternativeCompositeByteBuf buffer)
        {
            Logger.Debug("About to pass message {0} to {1}. Buffer to read: {2}.", Message, Message.SenderSocket, buffer.ReadableBytes);

            if (!Message.HasContent())
            {
                return(true);
            }

            int        size;
            IPublicKey receivedPublicKey;

            while (_contentTypes.Count > 0)
            {
                Message.Content content = _contentTypes.Peek();
                Logger.Debug("Go for content: {0}.", content);

                switch (content)
                {
                case Message.Content.Integer:
                    if (buffer.ReadableBytes < Utils.Utils.IntegerByteSize)
                    {
                        return(false);
                    }
                    Message.SetIntValue(buffer.ReadInt());
                    LastContent = _contentTypes.Dequeue();
                    break;

                case Message.Content.Long:
                    if (buffer.ReadableBytes < Utils.Utils.LongByteSize)
                    {
                        return(false);
                    }
                    Message.SetLongValue(buffer.ReadLong());
                    LastContent = _contentTypes.Dequeue();
                    break;

                case Message.Content.Key:
                    if (buffer.ReadableBytes < Number160.ByteArraySize)
                    {
                        return(false);
                    }
                    var keyBytes = new sbyte[Number160.ByteArraySize];
                    buffer.ReadBytes(keyBytes);
                    Message.SetKey(new Number160(keyBytes));
                    LastContent = _contentTypes.Dequeue();
                    break;

                case Message.Content.BloomFilter:
                    if (buffer.ReadableBytes < Utils.Utils.ShortByteSize)
                    {
                        return(false);
                    }
                    size = buffer.GetUShort(buffer.ReaderIndex);
                    if (buffer.ReadableBytes < size)
                    {
                        return(false);
                    }
                    Message.SetBloomFilter(new SimpleBloomFilter <Number160>(buffer));
                    LastContent = _contentTypes.Dequeue();
                    break;

                case Message.Content.SetNeighbors:
                    if (_neighborSize == -1 && buffer.ReadableBytes < Utils.Utils.ByteByteSize)
                    {
                        return(false);
                    }
                    if (_neighborSize == -1)
                    {
                        _neighborSize = buffer.ReadByte();
                    }
                    if (_neighborSet == null)
                    {
                        _neighborSet = new NeighborSet(-1, new List <PeerAddress>(_neighborSize));
                    }
                    for (int i = _neighborSet.Size; i < _neighborSize; i++)
                    {
                        if (buffer.ReadableBytes < Utils.Utils.ShortByteSize)
                        {
                            return(false);
                        }
                        int header = buffer.GetUShort(buffer.ReaderIndex);
                        size = PeerAddress.CalculateSize(header);
                        if (buffer.ReadableBytes < size)
                        {
                            return(false);
                        }
                        var pa = new PeerAddress(buffer);
                        _neighborSet.Add(pa);
                    }
                    Message.SetNeighborSet(_neighborSet);
                    LastContent   = _contentTypes.Dequeue();
                    _neighborSize = -1;     // TODO why here? not in prepareFinish()?
                    _neighborSet  = null;
                    break;

                case Message.Content.SetPeerSocket:
                    if (_peerSocketAddressSize == -1 && buffer.ReadableBytes < Utils.Utils.ByteByteSize)
                    {
                        return(false);
                    }
                    if (_peerSocketAddressSize == -1)
                    {
                        _peerSocketAddressSize = buffer.ReadUByte();
                    }
                    if (_peerSocketAddresses == null)
                    {
                        _peerSocketAddresses = new List <PeerSocketAddress>(_peerSocketAddressSize);
                    }
                    for (int i = _peerSocketAddresses.Count; i < _peerSocketAddressSize; i++)
                    {
                        if (buffer.ReadableBytes < Utils.Utils.ByteByteSize)
                        {
                            return(false);
                        }
                        int  header = buffer.GetUByte(buffer.ReaderIndex);
                        bool isIPv4 = header == 0;     // TODO check if works
                        size = PeerSocketAddress.Size(isIPv4);
                        if (buffer.ReadableBytes < size + Utils.Utils.ByteByteSize)
                        {
                            return(false);
                        }
                        // skip the ipv4/ipv6 header
                        buffer.SkipBytes(1);
                        _peerSocketAddresses.Add(PeerSocketAddress.Create(buffer, isIPv4));
                    }
                    Message.SetPeerSocketAddresses(_peerSocketAddresses);
                    LastContent            = _contentTypes.Dequeue();
                    _peerSocketAddressSize = -1;     // TODO why here? not in prepareFinish()?
                    _peerSocketAddresses   = null;
                    break;

                case Message.Content.SetKey640:
                    if (_keyCollectionSize == -1 && buffer.ReadableBytes < Utils.Utils.IntegerByteSize)
                    {
                        return(false);
                    }
                    if (_keyCollectionSize == -1)
                    {
                        _keyCollectionSize = buffer.ReadInt();
                    }
                    if (_keyCollection == null)
                    {
                        _keyCollection = new KeyCollection(new List <Number640>(_keyCollectionSize));
                    }
                    for (int i = _keyCollection.Size; i < _keyCollectionSize; i++)
                    {
                        if (buffer.ReadableBytes < 4 * Number160.ByteArraySize)
                        {
                            return(false);
                        }
                        var me = new sbyte[Number160.ByteArraySize];

                        buffer.ReadBytes(me);
                        var locationKey = new Number160(me);

                        buffer.ReadBytes(me);
                        var domainKey = new Number160(me);

                        buffer.ReadBytes(me);
                        var contentKey = new Number160(me);

                        buffer.ReadBytes(me);
                        var versionKey = new Number160(me);

                        _keyCollection.Add(new Number640(locationKey, domainKey, contentKey, versionKey));
                    }
                    Message.SetKeyCollection(_keyCollection);
                    LastContent        = _contentTypes.Dequeue();
                    _keyCollectionSize = -1;     // TODO why here? not in prepareFinish()?
                    _keyCollection     = null;
                    break;

                case Message.Content.MapKey640Data:
                    if (_mapSize == -1 && buffer.ReadableBytes < Utils.Utils.IntegerByteSize)
                    {
                        return(false);
                    }
                    if (_mapSize == -1)
                    {
                        _mapSize = buffer.ReadInt();
                    }
                    if (_dataMap == null)
                    {
                        _dataMap = new DataMap(new Dictionary <Number640, Data>(2 * _mapSize));
                    }
                    if (_data != null)
                    {
                        if (!_data.DecodeBuffer(buffer))
                        {
                            return(false);
                        }
                        if (!_data.DecodeDone(buffer, Message.PublicKey(0), _signatureFactory))
                        {
                            return(false);
                        }
                        _data = null;     // TODO why here? not in prepareFinish()?
                        _key  = null;
                    }
                    for (int i = _dataMap.Size; i < _mapSize; i++)
                    {
                        if (_key == null)
                        {
                            if (buffer.ReadableBytes < 4 * Number160.ByteArraySize)
                            {
                                return(false);
                            }
                            var me = new sbyte[Number160.ByteArraySize];
                            buffer.ReadBytes(me);
                            var locationKey = new Number160(me);
                            buffer.ReadBytes(me);
                            var domainKey = new Number160(me);
                            buffer.ReadBytes(me);
                            var contentKey = new Number160(me);
                            buffer.ReadBytes(me);
                            var versionKey = new Number160(me);

                            _key = new Number640(locationKey, domainKey, contentKey, versionKey);
                        }
                        _data = Data.DeocdeHeader(buffer, _signatureFactory);
                        if (_data == null)
                        {
                            return(false);
                        }
                        _dataMap.BackingDataMap.Add(_key, _data);

                        if (!_data.DecodeBuffer(buffer))
                        {
                            return(false);
                        }
                        if (!_data.DecodeDone(buffer, Message.PublicKey(0), _signatureFactory))
                        {
                            return(false);
                        }
                        // if we have signed the message, set the public key anyway, but only if we indicated so
                        if (Message.IsSign && Message.PublicKey(0) != null && _data.HasPublicKey &&
                            (_data.PublicKey == null || _data.PublicKey == PeerBuilder.EmptyPublicKey))
                        // TODO check empty key condition
                        {
                            _data.SetPublicKey(Message.PublicKey(0));
                        }
                        _data = null;     // TODO why here? not in prepareFinish()?
                        _key  = null;
                    }

                    Message.SetDataMap(_dataMap);
                    LastContent = _contentTypes.Dequeue();
                    _mapSize    = -1;  // TODO why here? not in prepareFinish()?
                    _dataMap    = null;
                    break;

                case Message.Content.MapKey640Keys:
                    if (_keyMap640KeysSize == -1 && buffer.ReadableBytes < Utils.Utils.IntegerByteSize)
                    {
                        return(false);
                    }
                    if (_keyMap640KeysSize == -1)
                    {
                        _keyMap640KeysSize = buffer.ReadInt();
                    }
                    if (_keyMap640Keys == null)
                    {
                        _keyMap640Keys = new KeyMap640Keys(new SortedDictionary <Number640, ICollection <Number160> >());
                        // TODO check TreeMap equivalent
                    }

                    const int meta = 4 * Number160.ByteArraySize;

                    for (int i = _keyMap640Keys.Size; i < _keyMap640KeysSize; i++)
                    {
                        if (buffer.ReadableBytes < meta + Utils.Utils.ByteByteSize)
                        {
                            return(false);
                        }
                        size = buffer.GetUByte(buffer.ReaderIndex + meta);

                        if (buffer.ReadableBytes <
                            meta + Utils.Utils.ByteByteSize + (size * Number160.ByteArraySize))
                        {
                            return(false);
                        }
                        var me = new sbyte[Number160.ByteArraySize];
                        buffer.ReadBytes(me);
                        var locationKey = new Number160(me);
                        buffer.ReadBytes(me);
                        var domainKey = new Number160(me);
                        buffer.ReadBytes(me);
                        var contentKey = new Number160(me);
                        buffer.ReadBytes(me);
                        var versionKey = new Number160(me);

                        int numBasedOn = buffer.ReadByte();
                        var value      = new HashSet <Number160>();
                        for (int j = 0; j < numBasedOn; j++)
                        {
                            buffer.ReadBytes(me);
                            var basedOnKey = new Number160(me);
                            value.Add(basedOnKey);
                        }

                        _keyMap640Keys.Put(new Number640(locationKey, domainKey, contentKey, versionKey), value);
                    }

                    Message.SetKeyMap640Keys(_keyMap640Keys);
                    LastContent        = _contentTypes.Dequeue();
                    _keyMap640KeysSize = -1;     // TODO why here? not in prepareFinish()?
                    _keyMap640Keys     = null;
                    break;

                case Message.Content.MapKey640Byte:
                    if (_keyMapByteSize == -1 && buffer.ReadableBytes < Utils.Utils.IntegerByteSize)
                    {
                        return(false);
                    }
                    if (_keyMapByteSize == -1)
                    {
                        _keyMapByteSize = buffer.ReadInt();
                    }
                    if (_keyMapByte == null)
                    {
                        _keyMapByte = new KeyMapByte(new Dictionary <Number640, sbyte>(2 * _keyMapByteSize));
                    }

                    for (int i = _keyMapByte.Size; i < _keyMapByteSize; i++)
                    {
                        if (buffer.ReadableBytes < 4 * Number160.ByteArraySize + 1)
                        {
                            return(false);
                        }
                        var me = new sbyte[Number160.ByteArraySize];
                        buffer.ReadBytes(me);
                        var locationKey = new Number160(me);
                        buffer.ReadBytes(me);
                        var domainKey = new Number160(me);
                        buffer.ReadBytes(me);
                        var contentKey = new Number160(me);
                        buffer.ReadBytes(me);
                        var versionKey = new Number160(me);

                        sbyte value = buffer.ReadByte();
                        _keyMapByte.Put(new Number640(locationKey, domainKey, contentKey, versionKey), value);
                    }

                    Message.SetKeyMapByte(_keyMapByte);
                    LastContent     = _contentTypes.Dequeue();
                    _keyMapByteSize = -1;     // TODO why here? not in prepareFinish()?
                    _keyMapByte     = null;
                    break;

                case Message.Content.ByteBuffer:
                    if (_bufferSize == -1 && buffer.ReadableBytes < Utils.Utils.IntegerByteSize)
                    {
                        return(false);
                    }
                    if (_bufferSize == -1)
                    {
                        _bufferSize = buffer.ReadInt();
                    }
                    if (_buffer == null)
                    {
                        _buffer = new DataBuffer();
                    }

                    int already   = _buffer.AlreadyTransferred;
                    int remaining = _bufferSize - already;
                    // already finished
                    if (remaining != 0)
                    {
                        int read = _buffer.TransferFrom(buffer, remaining);
                        if (read != remaining)
                        {
                            Logger.Debug(
                                "Still looking for data. Indicating that its not finished yet. Already Transferred = {0}, Size = {1}.",
                                _buffer.AlreadyTransferred, _bufferSize);
                            return(false);
                        }
                    }

                    ByteBuf buf2 = AlternativeCompositeByteBuf.CompBuffer(_buffer.ToByteBufs());
                    Message.SetBuffer(new Buffer(buf2, _bufferSize));
                    LastContent = _contentTypes.Dequeue();
                    _bufferSize = -1;
                    _buffer     = null;
                    break;

                case Message.Content.SetTrackerData:
                    if (_trackerDataSize == -1 && buffer.ReadableBytes < Utils.Utils.ByteByteSize)
                    {
                        return(false);
                    }
                    if (_trackerDataSize == -1)
                    {
                        _trackerDataSize = buffer.ReadUByte();
                    }
                    if (_trackerData == null)
                    {
                        _trackerData = new TrackerData(new Dictionary <PeerAddress, Data>(2 * _trackerDataSize));
                    }
                    if (_currentTrackerData != null)
                    {
                        if (!_currentTrackerData.DecodeBuffer(buffer))
                        {
                            return(false);
                        }
                        if (!_currentTrackerData.DecodeDone(buffer, Message.PublicKey(0), _signatureFactory))
                        {
                            return(false);
                        }
                        _currentTrackerData = null;
                    }
                    for (int i = _trackerData.Size; i < _trackerDataSize; i++)
                    {
                        if (buffer.ReadableBytes < Utils.Utils.ShortByteSize)
                        {
                            return(false);
                        }

                        int header = buffer.GetUShort(buffer.ReaderIndex);
                        size = PeerAddress.CalculateSize(header);
                        if (buffer.ReadableBytes < Utils.Utils.ShortByteSize)
                        {
                            return(false);
                        }
                        var pa = new PeerAddress(buffer);

                        _currentTrackerData = Data.DeocdeHeader(buffer, _signatureFactory);
                        if (_currentTrackerData == null)
                        {
                            return(false);
                        }
                        _trackerData.PeerAddresses.Add(pa, _currentTrackerData);
                        if (Message.IsSign)
                        {
                            _currentTrackerData.SetPublicKey(Message.PublicKey(0));
                        }
                        if (!_currentTrackerData.DecodeBuffer(buffer))
                        {
                            return(false);
                        }
                        if (!_currentTrackerData.DecodeDone(buffer, Message.PublicKey(0), _signatureFactory))
                        {
                            return(false);
                        }
                        _currentTrackerData = null;     // TODO why here?
                    }

                    Message.SetTrackerData(_trackerData);
                    LastContent      = _contentTypes.Dequeue();
                    _trackerDataSize = -1;
                    _trackerData     = null;
                    break;

                case Message.Content.PublicKey:     // fall-through
                case Message.Content.PublicKeySignature:
                    receivedPublicKey = _signatureFactory.DecodePublicKey(buffer);
                    if (content == Message.Content.PublicKeySignature)
                    {
                        if (receivedPublicKey == PeerBuilder.EmptyPublicKey)     // TODO check if works
                        {
                            // TODO throw InvalidKeyException
                            throw new SystemException("The public key cannot be empty.");
                        }
                    }
                    if (receivedPublicKey == null)
                    {
                        return(false);
                    }

                    Message.SetPublicKey(receivedPublicKey);
                    LastContent = _contentTypes.Dequeue();
                    break;

                default:
                    break;
                }
            }

            if (Message.IsSign)
            {
                var signatureEncode = _signatureFactory.SignatureCodec;
                size = signatureEncode.SignatureSize;
                if (buffer.ReadableBytes < size)
                {
                    return(false);
                }

                signatureEncode.Read(buffer);
                Message.SetReceivedSignature(signatureEncode);
            }
            return(true);
        }