Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Pär Björklund committed Aug 4, 2017
1 parent 152b2c1 commit 7ef44ae
Show file tree
Hide file tree
Showing 8 changed files with 150 additions and 19 deletions.
1 change: 1 addition & 0 deletions src/System.Net.Primitives/ref/System.Net.Primitives.cs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ public IPAddress(long newAddress) { }
public long ScopeId { get { throw null; } set { } }
public override bool Equals(object comparand) { throw null; }
public byte[] GetAddressBytes() { throw null; }
public bool TryWriteBytes(Span<byte> destination, out int bytesWritten) { throw null; }
public override int GetHashCode() { throw null; }
public static short HostToNetworkOrder(short host) { throw null; }
public static int HostToNetworkOrder(int host) { throw null; }
Expand Down
2 changes: 1 addition & 1 deletion src/System.Net.Primitives/ref/System.Net.Primitives.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@
<ProjectReference Include="..\..\System.Runtime.Handles\ref\System.Runtime.Handles.csproj" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>
</Project>
60 changes: 45 additions & 15 deletions src/System.Net.Primitives/src/System/Net/IPAddress.cs
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,49 @@ public static IPAddress Parse(string ipString)
return IPAddressParser.Parse(ipString, false);
}

public bool TryWriteBytes(Span<byte> destination, out int bytesWritten)
{
if (IsIPv6)
{
Debug.Assert(_numbers != null && _numbers.Length == NumberOfLabels);

if (destination.Length < IPAddressParserStatics.IPv6AddressBytes)
{
bytesWritten = 0;
return false;
}

int j = 0;
for (int i = 0; i < NumberOfLabels; i++)
{
destination[j++] = (byte)((_numbers[i] >> 8) & 0xFF);
destination[j++] = (byte)((_numbers[i]) & 0xFF);
}

bytesWritten = IPAddressParserStatics.IPv6AddressBytes;
}
else
{
if (destination.Length < IPAddressParserStatics.IPv4AddressBytes)
{
bytesWritten = 0;
return false;
}

uint address = PrivateAddress;
unchecked
{
destination[0] = (byte)(address);
destination[1] = (byte)(address >> 8);
destination[2] = (byte)(address >> 16);
destination[3] = (byte)(address >> 24);
}

bytesWritten = IPAddressParserStatics.IPv4AddressBytes;
}

return true;
}
/// <devdoc>
/// <para>
/// Provides a copy of the IPAddress internals as an array of bytes.
Expand All @@ -285,26 +328,13 @@ public byte[] GetAddressBytes()
Debug.Assert(_numbers != null && _numbers.Length == NumberOfLabels);

bytes = new byte[IPAddressParserStatics.IPv6AddressBytes];
int j = 0;
for (int i = 0; i < NumberOfLabels; i++)
{
bytes[j++] = (byte)((_numbers[i] >> 8) & 0xFF);
bytes[j++] = (byte)((_numbers[i]) & 0xFF);
}
}
else
{
uint address = PrivateAddress;
bytes = new byte[IPAddressParserStatics.IPv4AddressBytes];

unchecked
{
bytes[0] = (byte)(address);
bytes[1] = (byte)(address >> 8);
bytes[2] = (byte)(address >> 16);
bytes[3] = (byte)(address >> 24);
}
}

TryWriteBytes(new Span<byte>(bytes), out int bytesWritten);
return bytes;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<BuildConfigurations>
netstandard-Unix;
netstandard-Windows_NT;
netcoreapp
</BuildConfigurations>
</PropertyGroup>
</Project>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Collections.Generic;
using System.Net.Sockets;

using Xunit;

namespace System.Net.Primitives.Functional.Tests
{
public static class IPAddressSpanTest
{
private const long MinAddress = 0;
private const long MaxAddress = 0xFFFFFFFF;

private const long MinScopeId = 0;
private const long MaxScopeId = 0xFFFFFFFF;

private static byte[] ipV6AddressBytes1 = new byte[] { 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
private static byte[] ipV6AddressBytes2 = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };

private static IPAddress IPV6Address1()
{
return new IPAddress(ipV6AddressBytes1);
}

private static IPAddress IPV6Address2()
{
return new IPAddress(ipV6AddressBytes2);
}

[Theory]
[InlineData(new object[] { new byte[] { 0x8f, 0x18, 0x14, 0x24 } })]
[InlineData(new object[] { new byte[] { 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 } })]
public static void TryWriteBytes_RightSizeBuffer_Success(byte[] address)
{
var result = new byte[address.Length];
int bytesWritten = -1;
IPAddress ip = new IPAddress(address);
Assert.Equal(true, ip.TryWriteBytes(new Span<byte>(result), out bytesWritten));
Assert.Equal(address, result);
Assert.Equal(address.Length, bytesWritten);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Unix-Release|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Windows_NT-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Windows_NT-Release|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Release|AnyCPU'" />
<ItemGroup>
<Compile Include="CookieTest.cs" />
<Compile Include="CookieCollectionTest.cs" />
Expand All @@ -19,6 +21,7 @@
<Compile Include="EndPointTest.cs" />
<Compile Include="IPAddressParsing.cs" />
<Compile Include="IPAddressTest.cs" />
<Compile Include="IPAddressSpanTest.cs" Condition="'$(TargetGroup)' == 'netcoreapp'" />
<Compile Include="IPAddressMappingTest.cs" />
<Compile Include="IPEndPointTest.cs" />
<Compile Include="NetworkCredentialTest.cs" />
Expand All @@ -44,4 +47,4 @@
</ProjectReference>
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using Microsoft.Xunit.Performance;
using Xunit;

namespace System.Net.Primitives.Tests
{
public static class IPAddressPerformanceTests
{
[Benchmark]
[MeasureGCCounts]
[InlineData(new object[] { new byte[] { 0x8f, 0x18, 0x14, 0x24 } })]
[InlineData(new object[] { new byte[] { 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 } })]
public static void TryWriteBytes(byte[] address)
{
var ip = new IPAddress(address);
var bytes = new byte[address.Length];
var bytesSpan = new Span<byte>(bytes);
int bytesWritten = 0;
foreach (var iteration in Benchmark.Iterations)
{
using (iteration.StartMeasurement())
{
ip.TryWriteBytes(bytesSpan, bytesWritten);
}
}
}

[Benchmark]
[MeasureGCCounts]
[InlineData(new object[] { new byte[] { 0x8f, 0x18, 0x14, 0x24 } })]
[InlineData(new object[] { new byte[] { 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 } })]
public static void GetAddressBytes(byte[] address)
{
var ip = new IPAddress(address);
foreach (var iteration in Benchmark.Iterations)
{
using (iteration.StartMeasurement())
{
var bytes = ip.GetAddressBytes();
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Unix-Release|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Windows_NT-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Windows_NT-Release|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Release|AnyCPU'" />
<ItemGroup>
<Compile Include="CredentialCacheTests.cs" />
<Compile Include="IPAddressPerformanceTests.cs" Condition="'$(TargetGroup)' == 'netcoreapp'" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="$(CommonPath)\..\perf\PerfRunner\PerfRunner.csproj">
Expand All @@ -19,4 +22,4 @@
</ProjectReference>
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>
</Project>

0 comments on commit 7ef44ae

Please sign in to comment.