resolved conflicts with ByteBufferUtil

integrated ChannelId with EmbeddedChannel and added DefaultChannelIdTests
added copyright script and notices to all files
reformatted IChannelId, ChannelGroup, and other utility methods
This commit is contained in:
Aaron Stannard 2015-11-05 13:31:05 -08:00
Родитель e8cb7cfda1
Коммит 02ce951b8f
21 изменённых файлов: 443 добавлений и 248 удалений

Просмотреть файл

@ -367,16 +367,6 @@ namespace DotNetty.Buffers
return aLen - bLen;
}
/// <summary>
/// Toggles the endianness of the specified 16-bit long integer.
/// </summary>
public static short SwapShort(short value)
{
byte[] bytes = BitConverter.GetBytes(value);
Array.Reverse(bytes);
return BitConverter.ToInt16(bytes, 0);
}
/// <summary>
/// Toggles the endianness of the specified 64-bit long integer.
/// </summary>
@ -403,16 +393,6 @@ namespace DotNetty.Buffers
return (short)((((int)value & 0xFF) << 8) | (int)((value >> 8) & 0xFF));
}
/// <summary>
/// Toggles the endianness of the specified 32-bit long integer.
/// </summary>
public static int SwapInt(int value)
{
byte[] bytes = BitConverter.GetBytes(value);
Array.Reverse(bytes);
return BitConverter.ToInt32(bytes, 0);
}
/// <summary>
/// Read the given amount of bytes into a new {@link ByteBuf} that is allocated from the {@link ByteBufAllocator}.
/// </summary>

Просмотреть файл

@ -1,3 +1,7 @@
using System.Runtime.CompilerServices;
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System.Runtime.CompilerServices;
[assembly:InternalsVisibleTo("DotNetty.Common.Tests")]
[assembly:InternalsVisibleTo("DotNetty.Common.Tests")]

Просмотреть файл

@ -1,29 +1,28 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace DotNetty.Common.Utilities
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Text;
/// <summary>
/// String utility class.
/// String utility class.
/// </summary>
public static class StringUtil
{
public static readonly string Newline;
public const char DoubleQuote = '\"';
public const char Comma = ',';
public const char LineFeed = '\n';
public const char CarriageReturn = '\r';
public const char Tab = '\t';
public const byte UpperCaseToLowerCaseAsciiOffset = 'a' - 'A';
public static readonly string Newline;
static readonly string[] Byte2HexPad = new string[256];
static readonly string[] Byte2HexNopad = new string[256];
/**
* 2 - Quote character at beginning and end.
* 5 - Extra allowance for anticipated escape characters that may be added.
@ -65,9 +64,9 @@ namespace DotNetty.Common.Utilities
}
/// <summary>
/// Splits the specified {@link String} with the specified delimiter in maxParts maximum parts.
/// This operation is a simplified and optimized
/// version of {@link String#split(String, int)}.
/// Splits the specified {@link String} with the specified delimiter in maxParts maximum parts.
/// This operation is a simplified and optimized
/// version of {@link String#split(String, int)}.
/// </summary>
/// <param name="value"></param>
/// <param name="delim"></param>
@ -130,9 +129,9 @@ namespace DotNetty.Common.Utilities
}
/// <summary>
/// Get the item after one char delim if the delim is found (else null).
/// This operation is a simplified and optimized
/// version of {@link String#split(String, int)}.
/// Get the item after one char delim if the delim is found (else null).
/// This operation is a simplified and optimized
/// version of {@link String#split(String, int)}.
/// </summary>
/// <param name="value"></param>
/// <param name="delim"></param>
@ -144,7 +143,7 @@ namespace DotNetty.Common.Utilities
}
/// <summary>
/// Converts the specified byte value into a 2-digit hexadecimal integer.
/// Converts the specified byte value into a 2-digit hexadecimal integer.
/// </summary>
public static string ByteToHexStringPadded(int value)
{
@ -165,7 +164,7 @@ namespace DotNetty.Common.Utilities
//}
/// <summary>
/// Converts the specified byte array into a hexadecimal value.
/// Converts the specified byte array into a hexadecimal value.
/// </summary>
public static string ToHexStringPadded(byte[] src)
{
@ -173,7 +172,7 @@ namespace DotNetty.Common.Utilities
}
/// <summary>
/// Converts the specified byte array into a hexadecimal value.
/// Converts the specified byte array into a hexadecimal value.
/// </summary>
public static string ToHexStringPadded(byte[] src, int offset, int length)
{
@ -188,7 +187,7 @@ namespace DotNetty.Common.Utilities
public static StringBuilder ToHexStringPadded(StringBuilder sb, byte[] src, int offset, int length)
{
Contract.Requires((offset+length) <= src.Length);
Contract.Requires((offset + length) <= src.Length);
int end = offset + length;
for (int i = offset; i < end; i++)
{
@ -198,7 +197,7 @@ namespace DotNetty.Common.Utilities
}
/// <summary>
/// Converts the specified byte value into a hexadecimal integer.
/// Converts the specified byte value into a hexadecimal integer.
/// </summary>
public static string ByteToHexString(byte value)
{
@ -226,7 +225,7 @@ namespace DotNetty.Common.Utilities
}
/// <summary>
/// Converts the specified byte array into a hexadecimal value and appends it to the specified buffer.
/// Converts the specified byte array into a hexadecimal value and appends it to the specified buffer.
/// </summary>
public static StringBuilder ToHexString(StringBuilder dst, byte[] src, int offset, int length)
{
@ -255,11 +254,13 @@ namespace DotNetty.Common.Utilities
}
/// <summary>
/// Escapes the specified value, if necessary according to
/// <a href="https://tools.ietf.org/html/rfc4180#section-2">RFC-4180</a>.
/// Escapes the specified value, if necessary according to
/// <a href="https://tools.ietf.org/html/rfc4180#section-2">RFC-4180</a>.
/// </summary>
/// <param name="value">The value which will be escaped according to
/// <a href="https://tools.ietf.org/html/rfc4180#section-2">RFC-4180</a></param>
/// <param name="value">
/// The value which will be escaped according to
/// <a href="https://tools.ietf.org/html/rfc4180#section-2">RFC-4180</a>
/// </param>
/// <returns>the escaped value if necessary, or the value unchanged</returns>
public static string EscapeCsv(string value)
{
@ -299,7 +300,6 @@ namespace DotNetty.Common.Utilities
escaped.Append(DoubleQuote);
escapedDoubleQuote = true;
}
break;
}
break;
case LineFeed:

Просмотреть файл

@ -1,11 +1,13 @@
using System;
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace DotNetty.Common.Utilities
{
using System;
using System.Diagnostics.Contracts;
/// <summary>
/// A collection of utility methods to retrieve and parse the values of the .Net Environment properties.
/// A collection of utility methods to retrieve and parse the values of the .Net Environment properties.
/// </summary>
public static class SystemPropertyUtil
{
@ -21,7 +23,7 @@ namespace DotNetty.Common.Utilities
public static string Get(string key, string def)
{
Contract.Requires(string.IsNullOrWhiteSpace(key));
Contract.Requires(!string.IsNullOrWhiteSpace(key));
string value = null;
try
{

Просмотреть файл

@ -1,47 +1,49 @@
using DotNetty.Buffers;
using DotNetty.Common.Utilities;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace DotNetty.Transport.Channels
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using DotNetty.Buffers;
using DotNetty.Common.Internal.Logging;
using DotNetty.Common.Utilities;
[Serializable]
public class DefaultChannelId : IChannelId
{
//static readonly InternalLogger logger = InternalLoggerFactory.GetInstance(typeof(DefaultChannelId));
static readonly Regex MachineIdPattern = new Regex("^(?:[0-9a-fA-F][:-]?){6,8}$");
const int MachineIdLen = 8;
static readonly byte[] MachineId;
const int ProcessIdLen = 4;
// Maximal value for 64bit systems is 2^22. See man 5 proc.
// See https://github.com/netty/netty/issues/2706
const int MaxProcessId = 4194304;
static readonly int ProcessId;
const int SequenceLen = 4;
const int TimestampLen = 8;
const int RandomLen = 4;
static int nextSequence = 0;
static readonly IInternalLogger logger = InternalLoggerFactory.GetInstance<DefaultChannelId>();
static readonly Regex MachineIdPattern = new Regex("^(?:[0-9a-fA-F][:-]?){6,8}$");
static readonly byte[] MachineId;
static readonly int ProcessId;
static int nextSequence;
static int seed = (int)(Stopwatch.GetTimestamp() & 0xFFFFFFFF); //used to safly cast long to int, because the timestamp returned is long and it doesn't fit into an int
static readonly ThreadLocal<Random> ThreadLocalRandom = new ThreadLocal<Random>(() => new Random(Interlocked.Increment(ref seed))); //used to simulate java ThreadLocalRandom
readonly byte[] data = new byte[MachineIdLen + ProcessIdLen + SequenceLen + TimestampLen + RandomLen];
int hashCode;
[NonSerialized]
string shortValue;
string longValue;
[NonSerialized]
string longValue;
string shortValue;
static DefaultChannelId()
{
@ -50,17 +52,19 @@ namespace DotNetty.Transport.Channels
if (customProcessId != null)
{
if (!int.TryParse(customProcessId, out processId))
{
processId = -1;
}
}
if (processId < 0 || processId > MaxProcessId)
{
processId = -1;
//logger.warn("-Dio.netty.processId: {0} (malformed)", customProcessId);
logger.Warn("-Dio.netty.processId: {0} (malformed)", customProcessId);
}
else if (logger.DebugEnabled)
{
logger.Debug("-Dio.netty.processId: {0} (user-set)", processId);
}
//else if (logger.IsDebugEnabled())
//{
// logger.debug("-Dio.netty.processId: {0} (user-set)", processId);
//}
if (processId < 0)
{
processId = DefaultProcessId();
@ -83,11 +87,37 @@ namespace DotNetty.Transport.Channels
MachineId = machineId;
}
public string AsShortText()
{
string asShortText = this.shortValue;
if (asShortText == null)
{
this.shortValue = asShortText = ByteBufferUtil.HexDump(this.data, MachineIdLen + ProcessIdLen + SequenceLen + TimestampLen, RandomLen);
}
return asShortText;
}
public string AsLongText()
{
string asLongText = this.longValue;
if (asLongText == null)
{
this.longValue = asLongText = this.NewLongValue();
}
return asLongText;
}
public int CompareTo(IChannelId other)
{
return 0;
}
static byte[] ParseMachineId(string value)
{
// Strip separators.
value = value.Replace("[:-]", "");
byte[] machineId = new byte[MachineIdLen];
var machineId = new byte[MachineIdLen];
for (int i = 0; i < value.Length; i += 2)
{
machineId[i] = (byte)int.Parse(value.Substring(i, i + 2), NumberStyles.AllowHexSpecifier);
@ -97,8 +127,9 @@ namespace DotNetty.Transport.Channels
static int DefaultProcessId()
{
int pId = Process.GetCurrentProcess().Id;;
int pId = Process.GetCurrentProcess().Id;
;
if (pId <= 0)
{
pId = ThreadLocalRandom.Value.Next(MaxProcessId + 1);
@ -124,24 +155,24 @@ namespace DotNetty.Transport.Channels
{
foreach (NetworkInterface iface in NetworkInterface.GetAllNetworkInterfaces())
{
var addrs = iface.GetIPProperties().UnicastAddresses;
var addr = addrs.FirstOrDefault(a => !IPAddress.IsLoopback(a.Address));
UnicastIPAddressInformationCollection addrs = iface.GetIPProperties().UnicastAddresses;
UnicastIPAddressInformation addr = addrs.FirstOrDefault(a => !IPAddress.IsLoopback(a.Address));
if (addr != null)
{
ifaces.Add(iface, addr.Address);
}
}
}
//catch (SocketException e)
//{
// logger.warn("Failed to retrieve the list of available network interfaces", e);
//}
catch (SocketException e)
{
logger.Warn("Failed to retrieve the list of available network interfaces", e);
}
catch
{
// ignored
}
foreach (var entry in ifaces)
foreach (KeyValuePair<NetworkInterface, IPAddress> entry in ifaces)
{
NetworkInterface iface = entry.Key;
IPAddress addr = entry.Value;
@ -185,7 +216,7 @@ namespace DotNetty.Transport.Channels
switch (bestMacAddr.Length)
{
case 6: // EUI-48 - convert to EUI-64
byte[] newAddr = new byte[MachineIdLen];
var newAddr = new byte[MachineIdLen];
Array.Copy(bestMacAddr, 0, newAddr, 0, 3);
newAddr[3] = 0xFF;
newAddr[4] = 0xFE;
@ -290,32 +321,6 @@ namespace DotNetty.Transport.Channels
return 4;
}
public string AsShortText()
{
string asShortText = this.shortValue;
if (asShortText == null)
{
this.shortValue = asShortText = ByteBufferUtil.HexDump(this.data, MachineIdLen + ProcessIdLen + SequenceLen + TimestampLen, RandomLen);
}
return asShortText;
}
public string AsLongText()
{
string asLongText = this.longValue;
if (asLongText == null)
{
this.longValue = asLongText = this.NewLongValue();
}
return asLongText;
}
public int CompareTo(IChannelId other)
{
return 0;
}
string NewLongValue()
{
var buf = new StringBuilder(2 * this.data.Length + 5);
@ -405,7 +410,7 @@ namespace DotNetty.Transport.Channels
return false;
}
return Array.Equals(this.data, ((DefaultChannelId)obj).data);
return Equals(this.data, ((DefaultChannelId)obj).data);
}
public override string ToString()

Просмотреть файл

@ -41,7 +41,16 @@ namespace DotNetty.Transport.Channels.Embedded
/// Create a new instance with an empty pipeline.
/// </summary>
public EmbeddedChannel()
: this(EMPTY_HANDLERS)
: this(EmbeddedChannelId.Instance, EMPTY_HANDLERS)
{
}
/// <summary>
/// Create a new instance with an empty pipeline with the specified <see cref="IChannelId"/>.
/// </summary>
/// <param name="channelId">The <see cref="IChannelId"/> of this channel. </param>
public EmbeddedChannel(IChannelId channelId)
: this(channelId, EMPTY_HANDLERS)
{
}
@ -52,7 +61,19 @@ namespace DotNetty.Transport.Channels.Embedded
/// The <see cref="IChannelHandler"/>s that will be added to the <see cref="IChannelPipeline"/>
/// </param>
public EmbeddedChannel(params IChannelHandler[] handlers)
: base(null)
: this(EmbeddedChannelId.Instance, handlers)
{
}
/// <summary>
/// Create a new instance with the pipeline initialized with the specified handlers.
/// </summary>
/// <param name="id">The <see cref="IChannelId"/> of this channel.</param>
/// <param name="handlers">
/// The <see cref="IChannelHandler"/>s that will be added to the <see cref="IChannelPipeline"/>
/// </param>
public EmbeddedChannel(IChannelId id, params IChannelHandler[] handlers)
: base(null, id)
{
this.config = new DefaultChannelConfiguration(this);
if (handlers == null)

Просмотреть файл

@ -0,0 +1,54 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace DotNetty.Transport.Channels.Embedded
{
using System;
/// <summary>
/// A dummy <see cref="IChannelId"/> implementation
/// </summary>
public sealed class EmbeddedChannelId : IChannelId
{
public static readonly EmbeddedChannelId Instance = new EmbeddedChannelId();
EmbeddedChannelId()
{
}
public override int GetHashCode()
{
return 0;
}
public override bool Equals(object obj)
{
return obj is EmbeddedChannelId;
}
public int CompareTo(IChannelId other)
{
if (other is EmbeddedChannelId)
{
return 0;
}
return string.Compare(this.AsLongText(), other.AsLongText(), StringComparison.Ordinal);
}
public override string ToString()
{
return "embedded";
}
public string AsShortText()
{
return this.ToString();
}
public string AsLongText()
{
return this.ToString();
}
}
}

Просмотреть файл

@ -1,9 +1,13 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace DotNetty.Transport.Channels.Groups
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
public class ChannelGroupException : ChannelException, IEnumerable<KeyValuePair<IChannel, Exception>>
{
readonly IReadOnlyCollection<KeyValuePair<IChannel, Exception>> failed;
@ -26,7 +30,7 @@ namespace DotNetty.Transport.Channels.Groups
return this.failed.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
IEnumerator IEnumerable.GetEnumerator()
{
return this.failed.GetEnumerator();
}

Просмотреть файл

@ -1,7 +1,10 @@
using System;
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace DotNetty.Transport.Channels.Groups
{
using System;
public static class ChannelMatchers
{
static readonly IChannelMatcher AllMatcher = new AllChannelMatcher();

Просмотреть файл

@ -1,7 +1,10 @@
using System.Collections.Generic;
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace DotNetty.Transport.Channels.Groups
{
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
public sealed class CombinedEnumerator<E> : IEnumerator<E>
@ -29,7 +32,7 @@ namespace DotNetty.Transport.Channels.Groups
this.currentEnumerator.Dispose();
}
object System.Collections.IEnumerator.Current
object IEnumerator.Current
{
get { return this.Current; }
}

Просмотреть файл

@ -1,22 +1,26 @@
using DotNetty.Buffers;
using DotNetty.Common.Concurrency;
using DotNetty.Common.Utilities;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Threading;
using System.Threading.Tasks;
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace DotNetty.Transport.Channels.Groups
{
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Threading;
using System.Threading.Tasks;
using DotNetty.Buffers;
using DotNetty.Common.Concurrency;
using DotNetty.Common.Utilities;
public class DefaultChannelGroup : IChannelGroup
{
static int nextId = 0;
readonly string name;
static int nextId;
readonly IEventExecutor executor;
readonly ConcurrentDictionary<IChannelId, IChannel> serverChannels = new ConcurrentDictionary<IChannelId, IChannel>();
readonly string name;
readonly ConcurrentDictionary<IChannelId, IChannel> nonServerChannels = new ConcurrentDictionary<IChannelId, IChannel>();
readonly ConcurrentDictionary<IChannelId, IChannel> serverChannels = new ConcurrentDictionary<IChannelId, IChannel>();
public DefaultChannelGroup(IEventExecutor executor)
: this(string.Format("group-{0:X2}", Interlocked.Increment(ref nextId)), executor)
@ -33,6 +37,11 @@ namespace DotNetty.Transport.Channels.Groups
this.executor = executor;
}
public bool IsEmpty
{
get { return this.serverChannels.Count == 0 && this.nonServerChannels.Count == 0; }
}
public string Name
{
get { return this.name; }
@ -77,22 +86,6 @@ namespace DotNetty.Transport.Channels.Groups
return new DefaultChannelGroupCompletionSource(this, futures /*, this.executor*/).Task;
}
static object SafeDuplicate(object message)
{
if (message is IByteBuffer)
{
return ((IByteBuffer)message).Duplicate().Retain();
}
else if (message is IByteBufferHolder)
{
return ((IByteBufferHolder)message).Duplicate().Retain();
}
else
{
return ReferenceCountUtil.Retain(message);
}
}
public IChannelGroup Flush(IChannelMatcher matcher)
{
foreach (IChannel c in this.nonServerChannels.Values)
@ -121,27 +114,6 @@ namespace DotNetty.Transport.Channels.Groups
return this.GetHashCode() - other.GetHashCode();
}
public override bool Equals(object obj)
{
return this == obj;
}
public override string ToString()
{
return string.Format("{0}(name: {1}, size: {2})", this.GetType().Name, this.Name, this.Count);
}
public bool Add(IChannel channel)
{
var map = channel is IServerChannel ? this.serverChannels : this.nonServerChannels;
bool added = map.TryAdd(channel.Id, channel);
if (added)
{
channel.CloseCompletion.ContinueWith(x => this.Remove(channel));
}
return added;
}
void ICollection<IChannel>.Add(IChannel item)
{
this.Add(item);
@ -169,20 +141,6 @@ namespace DotNetty.Transport.Channels.Groups
public void CopyTo(IChannel[] array, int arrayIndex)
{
this.ToArray().CopyTo(array, arrayIndex);
}
public IChannel[] ToArray()
{
var channels = new List<IChannel>(this.Count);
channels.AddRange(this.serverChannels.Values);
channels.AddRange(this.nonServerChannels.Values);
return channels.ToArray();
}
public bool IsEmpty
{
get { return this.serverChannels.Count == 0 && this.nonServerChannels.Count == 0; }
}
public int Count
@ -208,47 +166,13 @@ namespace DotNetty.Transport.Channels.Groups
}
}
public bool Remove(IChannelId channelId)
{
IChannel ch = null;
if (this.serverChannels.TryRemove(channelId, out ch))
{
return true;
}
else if (this.nonServerChannels.TryRemove(channelId, out ch))
{
return true;
}
return false;
}
public bool Remove(object o)
{
var id = o as IChannelId;
if (id != null)
{
return this.Remove(id);
}
else
{
var channel = o as IChannel;
if (channel != null)
{
return this.Remove(channel);
}
}
return false;
}
public IEnumerator<IChannel> GetEnumerator()
{
return new CombinedEnumerator<IChannel>(this.serverChannels.Values.GetEnumerator(),
this.nonServerChannels.Values.GetEnumerator());
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
IEnumerator IEnumerable.GetEnumerator()
{
return new CombinedEnumerator<IChannel>(this.serverChannels.Values.GetEnumerator(),
this.nonServerChannels.Values.GetEnumerator());
@ -383,5 +307,84 @@ namespace DotNetty.Transport.Channels.Groups
return new DefaultChannelGroupCompletionSource(this, futures /*, this.executor*/).Task;
}
static object SafeDuplicate(object message)
{
if (message is IByteBuffer)
{
return ((IByteBuffer)message).Duplicate().Retain();
}
else if (message is IByteBufferHolder)
{
return ((IByteBufferHolder)message).Duplicate().Retain();
}
else
{
return ReferenceCountUtil.Retain(message);
}
}
public override bool Equals(object obj)
{
return this == obj;
}
public override string ToString()
{
return string.Format("{0}(name: {1}, size: {2})", this.GetType().Name, this.Name, this.Count);
}
public bool Add(IChannel channel)
{
ConcurrentDictionary<IChannelId, IChannel> map = channel is IServerChannel ? this.serverChannels : this.nonServerChannels;
bool added = map.TryAdd(channel.Id, channel);
if (added)
{
channel.CloseCompletion.ContinueWith(x => this.Remove(channel));
}
return added;
}
public IChannel[] ToArray()
{
var channels = new List<IChannel>(this.Count);
channels.AddRange(this.serverChannels.Values);
channels.AddRange(this.nonServerChannels.Values);
return channels.ToArray();
}
public bool Remove(IChannelId channelId)
{
IChannel ch = null;
if (this.serverChannels.TryRemove(channelId, out ch))
{
return true;
}
else if (this.nonServerChannels.TryRemove(channelId, out ch))
{
return true;
}
return false;
}
public bool Remove(object o)
{
var id = o as IChannelId;
if (id != null)
{
return this.Remove(id);
}
else
{
var channel = o as IChannel;
if (channel != null)
{
return this.Remove(channel);
}
}
return false;
}
}
}

Просмотреть файл

@ -1,18 +1,21 @@
using DotNetty.Common.Concurrency;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Threading.Tasks;
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace DotNetty.Transport.Channels.Groups
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Threading.Tasks;
public class DefaultChannelGroupCompletionSource : TaskCompletionSource<int>, IChannelGroupTaskCompletionSource
{
readonly IChannelGroup group;
readonly Dictionary<IChannel, Task> futures;
int successCount;
readonly IChannelGroup group;
int failureCount;
int successCount;
public DefaultChannelGroupCompletionSource(IChannelGroup group, Dictionary<IChannel, Task> futures /*, IEventExecutor executor*/)
: this(group, futures /*,executor*/, null)
@ -26,7 +29,7 @@ namespace DotNetty.Transport.Channels.Groups
Contract.Requires(futures != null);
this.group = group;
foreach (var pair in futures)
foreach (KeyValuePair<IChannel, Task> pair in futures)
{
this.futures.Add(pair.Key, pair.Value);
pair.Value.ContinueWith(x =>
@ -128,7 +131,7 @@ namespace DotNetty.Transport.Channels.Groups
this.futures.Values.GetEnumerator().Dispose();
}
object System.Collections.IEnumerator.Current
object IEnumerator.Current
{
get { return this.futures.Values.GetEnumerator().Current; }
}
@ -140,7 +143,7 @@ namespace DotNetty.Transport.Channels.Groups
public void Reset()
{
((System.Collections.IEnumerator)this.futures.Values.GetEnumerator()).Reset();
((IEnumerator)this.futures.Values.GetEnumerator()).Reset();
}
}
}

Просмотреть файл

@ -1,14 +1,17 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace DotNetty.Transport.Channels.Groups
{
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
public interface IChannelGroup : ICollection<IChannel>, IComparable<IChannelGroup>
{
/// <summary>
/// Returns the name of this group. A group name is purely for helping
/// you to distinguish one group from others.
/// Returns the name of this group. A group name is purely for helping
/// you to distinguish one group from others.
/// </summary>
string Name { get; }

Просмотреть файл

@ -1,12 +1,17 @@
using System.Collections.Generic;
using System.Threading.Tasks;
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace DotNetty.Transport.Channels.Groups
{
using System.Collections.Generic;
using System.Threading.Tasks;
public interface IChannelGroupTaskCompletionSource : IEnumerator<Task>
{
IChannelGroup Group { get; }
ChannelGroupException Cause { get; }
Task Find(IChannel channel);
bool IsPartialSucess();
@ -14,7 +19,5 @@ namespace DotNetty.Transport.Channels.Groups
bool IsSucess();
bool IsPartialFailure();
ChannelGroupException Cause { get; }
}
}

Просмотреть файл

@ -1,4 +1,7 @@
namespace DotNetty.Transport.Channels.Groups
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace DotNetty.Transport.Channels.Groups
{
public interface IChannelMatcher
{

Просмотреть файл

@ -1,12 +1,14 @@

using System;
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace DotNetty.Transport.Channels
{
using System;
public interface IChannelId : IComparable<IChannelId>
{
string AsShortText();
string AsLongText();
}
}
}

Просмотреть файл

@ -60,6 +60,7 @@
<Compile Include="Channels\DefaultChannelPipeline.cs" />
<Compile Include="Channels\DefaultMessageSizeEstimator.cs" />
<Compile Include="Channels\Embedded\EmbeddedChannel.cs" />
<Compile Include="Channels\Embedded\EmbeddedChannelId.cs" />
<Compile Include="Channels\Embedded\EmbeddedEventLoop.cs" />
<Compile Include="Channels\Embedded\EmbeddedSocketAddress.cs" />
<Compile Include="Channels\FixedRecvByteBufAllocator.cs" />

Просмотреть файл

@ -1,7 +1,11 @@
// <auto-generated/>
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
// <auto-generated/>
using System.Reflection;
[assembly: AssemblyCompanyAttribute("DotNetty")]
[assembly: AssemblyCopyrightAttribute("Copyright © 2015")]
[assembly: AssemblyVersionAttribute("0.1.3")]
[assembly: AssemblyFileVersionAttribute("0.1.3")]

Просмотреть файл

@ -0,0 +1,45 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace DotNetty.Transport.Tests.Channel
{
using System.Text.RegularExpressions;
using DotNetty.Transport.Channels;
using Xunit;
public class DefaulChannelIdTest
{
[Fact]
public void TestShortText()
{
string text = DefaultChannelId.NewInstance().AsShortText();
Assert.True(Regex.IsMatch(text, @"^[0-9a-f]{8}$"));
}
[Fact]
public void TestLongText()
{
string text = DefaultChannelId.NewInstance().AsLongText();
Assert.True(Regex.IsMatch(text, @"^[0-9a-f]{16}-[0-9a-f]{8}-[0-9a-f]{8}-[0-9a-f]{16}-[0-9a-f]{8}$"));
}
[Fact]
public void TestIdempotentMachineId()
{
string a = DefaultChannelId.NewInstance().AsLongText().Substring(0, 8);
string b = DefaultChannelId.NewInstance().AsLongText().Substring(0, 8);
Assert.Equal(a, b);
}
[Fact]
public void TestIdempotentProcessId()
{
string a = DefaultChannelId.NewInstance().AsLongText().Substring(9, 4);
string b = DefaultChannelId.NewInstance().AsLongText().Substring(9, 4);
Assert.Equal(a, b);
}
// TODO: port TestSerialization https://github.com/netty/netty/blob/master/transport/src/test/java/io/netty/channel/DefaultChannelIdTest.java
// requires ByteBufOutputStream and InputStream
}
}

Просмотреть файл

@ -61,6 +61,7 @@
<Otherwise />
</Choose>
<ItemGroup>
<Compile Include="Channel\DefaulChannelIdTest.cs" />
<Compile Include="Channel\Embedded\EmbeddedChannelTest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>

Просмотреть файл

@ -0,0 +1,51 @@
$lineBreak = "`r`n"
$noticeTemplate = "// Copyright (c) Microsoft. All rights reserved.$lineBreak// Licensed under the MIT license. See LICENSE file in the project root for full license information.$lineBreak$lineBreak"
$tokenToReplace = [regex]::Escape("[FileName]")
Function CreateFileSpecificNotice($sourcePath){
$fileName = Split-Path $sourcePath -Leaf
$fileSpecificNotice = $noticeTemplate -replace $tokenToReplace, $fileName
return $fileSpecificNotice
}
Function SourceFileContainsNotice($sourcePath){
$copyrightSnippet = [regex]::Escape("// Copyright (c) Microsoft")
$fileSpecificNotice = CreateFileSpecificNotice($sourcePath)
$arrMatchResults = Get-Content $sourcePath | Select-String $copyrightSnippet
if ($arrMatchResults -ne $null -and $arrMatchResults.count -gt 0){
return $true
}
else{
return $false
}
}
Function AddHeaderToSourceFile($sourcePath) {
# "Source path is: $sourcePath"
$containsNotice = SourceFileContainsNotice($sourcePath)
# "Contains notice: $containsNotice"
if ($containsNotice){
#"Source file already contains notice -- not adding"
}
else {
#"Source file does not contain notice -- adding"
$noticeToInsert = CreateFileSpecificNotice($sourcePath)
$fileLines = (Get-Content $sourcePath) -join $lineBreak
$content = $noticeToInsert + $fileLines + $lineBreak
$content | Out-File $sourcePath -Encoding utf8
}
}
$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
$parent = (get-item $scriptPath).Parent.FullName
$startingPath = "$parent\src"
Get-ChildItem $startingPath\*.cs -Recurse | Select FullName | Foreach-Object { AddHeaderToSourceFile($_.FullName)}
Get-ChildItem $startingPath\*.fs -Recurse | Select FullName | Foreach-Object { AddHeaderToSourceFile($_.FullName)}