예제 #1
0
        private bool Loop(AlternativeCompositeByteBuf buffer)
        {
            MessageContentIndex next;

            while ((next = Message.ContentReferences.Peek2()) != null)
            {
                long            start   = buffer.WriterIndex;
                Message.Content content = next.Content;

                switch (content)
                {
                case Message.Content.Key:
                    buffer.WriteBytes(Message.Key(next.Index).ToByteArray());
                    Message.ContentReferences.Dequeue();
                    break;

                case Message.Content.Integer:
                    buffer.WriteInt(Message.IntAt(next.Index));
                    Message.ContentReferences.Dequeue();
                    break;

                case Message.Content.Long:
                    buffer.WriteLong(Message.LongAt(next.Index));
                    Message.ContentReferences.Dequeue();
                    break;

                case Message.Content.SetNeighbors:
                    var neighborSet = Message.NeighborsSet(next.Index);
                    // write length
                    buffer.WriteByte((sbyte)neighborSet.Size);
                    foreach (var neighbor in neighborSet.Neighbors)
                    {
                        buffer.WriteBytes(neighbor.ToByteArray());
                    }
                    Message.ContentReferences.Dequeue();
                    break;

                case Message.Content.SetPeerSocket:
                    var list = Message.PeerSocketAddresses;
                    // write length
                    buffer.WriteByte((sbyte)list.Count);
                    foreach (var psa in list)
                    {
                        // write IP version flag
                        buffer.WriteByte(psa.IsIPv4 ? 0 : 1);
                        buffer.WriteBytes(psa.ToByteArray());
                    }
                    Message.ContentReferences.Dequeue();
                    break;

                case Message.Content.BloomFilter:
                    var bf = Message.BloomFilter(next.Index);
                    bf.ToByteBuffer(buffer);
                    Message.ContentReferences.Dequeue();
                    break;

                case Message.Content.SetKey640:
                    var keys = Message.KeyCollection(next.Index);
                    // write length
                    buffer.WriteInt(keys.Size);
                    if (keys.IsConvert)
                    {
                        foreach (var key in keys.KeysConvert)
                        {
                            buffer.WriteBytes(keys.LocationKey.ToByteArray());
                            buffer.WriteBytes(keys.DomainKey.ToByteArray());
                            buffer.WriteBytes(key.ToByteArray());
                            buffer.WriteBytes(keys.VersionKey.ToByteArray());
                        }
                    }
                    else
                    {
                        foreach (var key in keys.Keys)
                        {
                            buffer.WriteBytes(key.LocationKey.ToByteArray());
                            buffer.WriteBytes(key.DomainKey.ToByteArray());
                            buffer.WriteBytes(key.ContentKey.ToByteArray());
                            buffer.WriteBytes(key.VersionKey.ToByteArray());
                        }
                    }
                    Message.ContentReferences.Dequeue();
                    break;

                case Message.Content.MapKey640Data:
                    var dm = Message.DataMap(next.Index);
                    // write length
                    buffer.WriteInt(dm.Size);
                    if (dm.IsConvert)
                    {
                        foreach (var data in dm.DataMapConvert)
                        {
                            buffer.WriteBytes(dm.LocationKey.ToByteArray());
                            buffer.WriteBytes(dm.DomainKey.ToByteArray());
                            buffer.WriteBytes(data.Key.ToByteArray());
                            buffer.WriteBytes(dm.VersionKey.ToByteArray());

                            EncodeData(buffer, data.Value, dm.IsConvertMeta, !Message.IsRequest());
                        }
                    }
                    else
                    {
                        foreach (var data in dm.BackingDataMap)
                        {
                            buffer.WriteBytes(data.Key.LocationKey.ToByteArray());
                            buffer.WriteBytes(data.Key.DomainKey.ToByteArray());
                            buffer.WriteBytes(data.Key.ContentKey.ToByteArray());
                            buffer.WriteBytes(data.Key.VersionKey.ToByteArray());

                            EncodeData(buffer, data.Value, dm.IsConvertMeta, !Message.IsRequest());
                        }
                    }
                    Message.ContentReferences.Dequeue();
                    break;

                case Message.Content.MapKey640Keys:
                    var kmk = Message.KeyMap640Keys(next.Index);
                    // write length
                    buffer.WriteInt(kmk.Size);
                    foreach (var data in kmk.KeysMap)
                    {
                        buffer.WriteBytes(data.Key.LocationKey.ToByteArray());
                        buffer.WriteBytes(data.Key.DomainKey.ToByteArray());
                        buffer.WriteBytes(data.Key.ContentKey.ToByteArray());
                        buffer.WriteBytes(data.Key.VersionKey.ToByteArray());

                        // write number of based-on keys
                        buffer.WriteByte((sbyte)data.Value.Count);

                        // write based-on keys
                        foreach (var key in data.Value)
                        {
                            buffer.WriteBytes(key.ToByteArray());
                        }
                    }
                    Message.ContentReferences.Dequeue();
                    break;

                case Message.Content.MapKey640Byte:
                    var kmb = Message.KeyMapByte(next.Index);
                    // write length
                    buffer.WriteInt(kmb.Size);
                    foreach (var data in kmb.KeysMap)
                    {
                        buffer.WriteBytes(data.Key.LocationKey.ToByteArray());
                        buffer.WriteBytes(data.Key.DomainKey.ToByteArray());
                        buffer.WriteBytes(data.Key.ContentKey.ToByteArray());
                        buffer.WriteBytes(data.Key.VersionKey.ToByteArray());

                        // write byte
                        buffer.WriteByte(data.Value);
                    }
                    Message.ContentReferences.Dequeue();
                    break;

                case Message.Content.ByteBuffer:
                    var b = Message.Buffer(next.Index);
                    if (!_resume)
                    {
                        buffer.WriteInt(b.Length);
                    }
                    // write length
                    int readable = b.Readable;
                    buffer.WriteBytes(b.BackingBuffer, readable);
                    if (b.IncRead(readable) == b.Length)
                    {
                        Message.ContentReferences.Dequeue();
                    }
                    else if (Message.IsStreaming())
                    {
                        Logger.Debug("Partial message of length {0} sent.", readable);
                        return(false);
                    }
                    else
                    {
                        const string description = "Larger buffer has been announced, but not in message streaming mode. This is wrong.";
                        Logger.Error(description);
                        throw new SystemException(description);
                    }
                    break;

                case Message.Content.SetTrackerData:
                    var td = Message.TrackerData(next.Index);
                    // write length
                    buffer.WriteByte((sbyte)td.PeerAddresses.Count);      // TODO remove cast
                    foreach (var data in td.PeerAddresses)
                    {
                        var me = data.Key.ToByteArray();
                        buffer.WriteBytes(me);

                        var d = data.Value.Duplicate();
                        EncodeData(buffer, d, false, !Message.IsRequest());
                    }
                    Message.ContentReferences.Dequeue();
                    break;

                case Message.Content.PublicKeySignature:
                    // flag to encode public key
                    Message.SetHintSign();
                    // then, do the regular public key stuff -> no break
                    goto case Message.Content.PublicKey;     // TODO check, else duplicate code

                case Message.Content.PublicKey:
                    var pk = Message.PublicKey(next.Index);
                    _signatureFactory.EncodePublicKey(pk, buffer);
                    Message.ContentReferences.Dequeue();
                    break;

                default:
                    throw new SystemException("Unknown type: " + next.Content);
                }

                Logger.Debug("Wrote in encoder for {0} {1}.", content, buffer.WriterIndex - start);
            }
            return(true);
        }
예제 #2
0
파일: Data.cs 프로젝트: lanicon/TomP2P.NET
        public void EncodeHeader(AlternativeCompositeByteBuf buffer, ISignatureFactory signatureFactory)
        {
            int header = (int)_type; // TODO check if works

            if (HasPrepareFlag)
            {
                header |= 0x02;
            }
            if (IsFlag1)
            {
                header |= 0x04;
            }
            if (IsFlag2)
            {
                header |= 0x08;
            }
            if (_ttl)
            {
                header |= 0x10;
            }
            if (IsSigned && HasPublicKey && IsProtectedEntry)
            {
                header |= (0x20 | 0x40);
            }
            else if (IsSigned && HasPublicKey)
            {
                header |= 0x40;
            }
            else if (HasPublicKey)
            {
                header |= 0x20;
            }
            if (_basedOnFlag)
            {
                header |= 0x80;
            }
            switch (_type)
            {
            case DataType.Small:
                buffer.WriteByte((sbyte)header);     // TODO remove cast
                buffer.WriteByte((sbyte)Length);
                break;

            case DataType.Large:
                buffer.WriteByte((sbyte)header);     // TODO remove cast
                buffer.WriteInt(Length);
                break;

            default:
                throw new ArgumentException("Unknown DataType.");
            }
            if (_ttl)
            {
                buffer.WriteInt(TtlSeconds);
            }
            if (_basedOnFlag)
            {
                buffer.WriteByte((sbyte)(BasedOnSet.Count() - 1)); // TODO remove cast
                foreach (var basedOn in BasedOnSet)
                {
                    buffer.WriteBytes(basedOn.ToByteArray());
                }
            }
            if (HasPublicKey)
            {
                if (PublicKey == null)
                {
                    buffer.WriteShort(0);
                }
                else
                {
                    signatureFactory.EncodePublicKey(PublicKey, buffer);
                }
            }
        }