Merge branch 'master' into jamesmcroft/3506-carousel-automation

This commit is contained in:
James Croft 2021-02-24 18:07:48 +00:00 коммит произвёл GitHub
Родитель 32b015dc7b 14880e31c8
Коммит df21fcac0b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
624 изменённых файлов: 4232 добавлений и 13646 удалений

4
.github/ISSUE_TEMPLATE/bug_report.md поставляемый
Просмотреть файл

@ -7,7 +7,9 @@ assignees: ''
---
<!-- 🚨 Please Do Not skip any instructions and information mentioned below as they are all required and essential to investigate the issue. Issues with missing information may be closed without investigation 🚨 -->
<!-- 🚨 PLEASE DO NOT SKIP ANY INSTRUCTIONS AND INFORMATION MENTIONED BELOW AS THEY ARE ALL REQUIRED AND ESSENTIAL TO INVESTIGATE THE ISSUE. ISSUES WITH MISSING INFORMATION MAY BE CLOSED WITHOUT INVESTIGATION
...
IF NOT CERTAIN ABOUT THE ISSUE AND REQUIRE MORE CLARITY THEN PLEASE POST ON "QUESTIONS & HELP" CATEGORY OF THE DISCUSSIONS PLATFORM [https://github.com/windows-toolkit/WindowsCommunityToolkit/discussions/categories/questions-help] WHERE YOU CAN DISCUSS AND ENAGAGE WITH THE COMMUNITY TO GAIN FURTHER CLAIRITY REGARDING THE ISSUE 🚨 -->
## Describe the bug
A clear and concise description of what the bug is.

4
.github/ISSUE_TEMPLATE/feature_request.md поставляемый
Просмотреть файл

@ -7,7 +7,9 @@ assignees: ''
---
<!-- 🚨 Please provide detailed information and Do Not skip any instructions as they are all required and essential to help us understand the feature 🚨 -->
<!-- 🚨 PLEASE PROVIDE DETAILED INFORMATION AND DO NOT SKIP ANY INSTRUCTIONS AND INFORMATION MENTIONED BELOW AS THEY ARE ALL REQUIRED AND ESSENTIAL TO HELP US UNDERSTAND THE FEATURE.
...
IF NOT CERTAIN ABOUT THE FEATURE AND REQUIRE MORE CLARITY THEN PLEASE POST ON "IDEAS" CATEGORY OF THE DISCUSSIONS PLATFORM [https://github.com/windows-toolkit/WindowsCommunityToolkit/discussions/categories/ideas] WHERE YOU CAN DISCUSS AND ENAGAGE WITH THE COMMUNITY TO GAIN FURTHER CLAIRITY REGARDING THE FEATURE 🚨 -->
## Describe the problem this feature would solve
<!-- Please describe or link to any existing issues or discussions.

5
.github/ISSUE_TEMPLATE/question.md поставляемый
Просмотреть файл

@ -12,8 +12,9 @@ Hi!
We try and keep our GitHub issue list for bugs and features.
Ideally, it'd be great to post your question on Stack Overflow using the 'windows-community-toolkit' tag here: https://stackoverflow.com/questions/tagged/windows-community-toolkit
🚨 Please provide detailed information that includes examples, screenshots, and relevant issues if possible 🚨
Ideally, it'd be great to post your question on Stack Overflow using the 'windows-community-toolkit' tag here: https://stackoverflow.com/questions/tagged/windows-community-toolkit OR you may ask the question on "Questions & Help" category of the Discussions platform [https://github.com/windows-toolkit/WindowsCommunityToolkit/discussions/categories/questions-help]
🚨 PLEASE PROVIDE DETAILED INFORMATION THAT INCLUDE EXAMPLES, SCREENSHOTS, AND RELEVANT ISSUES IF POSSIBLE 🚨
If this is more about a scenario that you think is missing documentation, please file an issue instead at https://github.com/MicrosoftDocs/WindowsCommunityToolkitDocs/issues/new

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

@ -5,8 +5,9 @@
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<NoPackageAnalysis>true</NoPackageAnalysis>
<PackageIconUrl>https://raw.githubusercontent.com/windows-toolkit/WindowsCommunityToolkit/master/build/nuget.png</PackageIconUrl>
<PackageIcon>images\nuget.png</PackageIcon>
<PackageProjectUrl>https://github.com/windows-toolkit/WindowsCommunityToolkit</PackageProjectUrl>
<PackageLicenseUrl>https://github.com/windows-toolkit/WindowsCommunityToolkit/blob/master/license.md</PackageLicenseUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageReleaseNotes>https://github.com/windows-toolkit/WindowsCommunityToolkit/releases</PackageReleaseNotes>
<Copyright>(c) .NET Foundation and Contributors. All rights reserved.</Copyright>
<DefaultLanguage>en-US</DefaultLanguage>
@ -95,13 +96,15 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Nerdbank.GitVersioning" Version="3.1.91" PrivateAssets="all" />
<PackageReference Include="Nerdbank.GitVersioning" Version="3.3.37" PrivateAssets="all" />
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="$(MSBuildThisFileDirectory)stylecop.json">
<Link>stylecop.json</Link>
</AdditionalFiles>
<None Include="$(MSBuildThisFileDirectory)license.md" Pack="true" PackagePath="\"/>
<None Include="$(MSBuildThisFileDirectory)build\nuget.png" Pack="true" PackagePath="images\"/>
</ItemGroup>
<Import Project="$(MSBuildThisFileDirectory)build\Windows.Toolkit.VisualStudio.Design.props" Condition="'$(IsDesignProject)' == 'true'"/>

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

@ -150,7 +150,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
<Version>6.2.10</Version>
<Version>6.2.12</Version>
</PackageReference>
<PackageReference Include="StyleCop.Analyzers">
<Version>1.0.2</Version>

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

@ -11,7 +11,7 @@ using System.Reflection;
#endif
using System.Runtime.CompilerServices;
namespace Microsoft.Toolkit.Extensions
namespace Microsoft.Toolkit.Diagnostics
{
/// <summary>
/// Helpers for working with types.

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

@ -7,7 +7,7 @@ using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Microsoft.Toolkit.Extensions
namespace Microsoft.Toolkit.Diagnostics
{
/// <summary>
/// Helpers for working with value types.

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

@ -8,7 +8,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Microsoft.Toolkit.Extensions;
namespace Microsoft.Toolkit.Diagnostics
{

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

@ -5,7 +5,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Microsoft.Toolkit.Extensions;
namespace Microsoft.Toolkit.Diagnostics
{

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

@ -6,9 +6,6 @@ using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
#if NETSTANDARD1_4
using Microsoft.Toolkit.Extensions;
#endif
namespace Microsoft.Toolkit.Diagnostics
{

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

@ -4,7 +4,6 @@
using System;
using System.Diagnostics.CodeAnalysis;
using Microsoft.Toolkit.Extensions;
namespace Microsoft.Toolkit.Diagnostics
{

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

@ -4,7 +4,6 @@
using System;
using System.Diagnostics.CodeAnalysis;
using Microsoft.Toolkit.Extensions;
namespace Microsoft.Toolkit.Diagnostics
{

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

@ -4,7 +4,6 @@
using System;
using System.Diagnostics.CodeAnalysis;
using Microsoft.Toolkit.Extensions;
namespace Microsoft.Toolkit.Diagnostics
{

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

@ -5,7 +5,6 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using Microsoft.Toolkit.Extensions;
namespace Microsoft.Toolkit.Diagnostics
{

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

@ -5,7 +5,6 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks;
using Microsoft.Toolkit.Extensions;
namespace Microsoft.Toolkit.Diagnostics
{

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

@ -5,7 +5,6 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
using Microsoft.Toolkit.Extensions;
namespace Microsoft.Toolkit.Diagnostics
{

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

@ -9,7 +9,6 @@ using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Microsoft.Toolkit.HighPerformance.Buffers.Views;
using Microsoft.Toolkit.HighPerformance.Extensions;
using Microsoft.Toolkit.HighPerformance.Helpers.Internals;
namespace Microsoft.Toolkit.HighPerformance.Buffers

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

@ -7,7 +7,6 @@ using System.Buffers;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Microsoft.Toolkit.HighPerformance.Buffers.Internals.Interfaces;
using Microsoft.Toolkit.HighPerformance.Extensions;
using RuntimeHelpers = Microsoft.Toolkit.HighPerformance.Helpers.Internals.RuntimeHelpers;
namespace Microsoft.Toolkit.HighPerformance.Buffers.Internals

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

@ -8,7 +8,7 @@ using System;
using System.Buffers;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Microsoft.Toolkit.HighPerformance.Extensions;
using Microsoft.Toolkit.HighPerformance.Helpers;
namespace Microsoft.Toolkit.HighPerformance.Buffers.Internals
{
@ -49,7 +49,7 @@ namespace Microsoft.Toolkit.HighPerformance.Buffers.Internals
/// <inheritdoc/>
public override Span<T> GetSpan()
{
ref T r0 = ref this.instance.DangerousGetObjectDataReferenceAt<T>(this.offset);
ref T r0 = ref ObjectMarshal.DangerousGetObjectDataReferenceAt<T>(this.instance, this.offset);
return MemoryMarshal.CreateSpan(ref r0, this.length);
}
@ -68,7 +68,7 @@ namespace Microsoft.Toolkit.HighPerformance.Buffers.Internals
// traditional means (eg. via the implicit T[] array conversion), if T is a
// reference type or a type containing some references.
GCHandle handle = GCHandle.Alloc(this.instance, GCHandleType.Pinned);
ref T r0 = ref this.instance.DangerousGetObjectDataReferenceAt<T>(this.offset);
ref T r0 = ref ObjectMarshal.DangerousGetObjectDataReferenceAt<T>(this.instance, this.offset);
ref T r1 = ref Unsafe.Add(ref r0, (nint)(uint)elementIndex);
void* p = Unsafe.AsPointer(ref r1);

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

@ -7,7 +7,6 @@ using System.Buffers;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Microsoft.Toolkit.HighPerformance.Buffers.Internals.Interfaces;
using Microsoft.Toolkit.HighPerformance.Extensions;
using RuntimeHelpers = Microsoft.Toolkit.HighPerformance.Helpers.Internals.RuntimeHelpers;
namespace Microsoft.Toolkit.HighPerformance.Buffers.Internals

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

@ -11,7 +11,6 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
#endif
using Microsoft.Toolkit.HighPerformance.Buffers.Views;
using Microsoft.Toolkit.HighPerformance.Extensions;
namespace Microsoft.Toolkit.HighPerformance.Buffers
{

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

@ -11,7 +11,6 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
#endif
using Microsoft.Toolkit.HighPerformance.Buffers.Views;
using Microsoft.Toolkit.HighPerformance.Extensions;
namespace Microsoft.Toolkit.HighPerformance.Buffers
{

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

@ -7,7 +7,6 @@ using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
using System.Text;
using Microsoft.Toolkit.HighPerformance.Extensions;
#if !NETSTANDARD1_4
using Microsoft.Toolkit.HighPerformance.Helpers;
#endif

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

@ -8,7 +8,6 @@ using System.Runtime.CompilerServices;
#if SPAN_RUNTIME_SUPPORT
using System.Runtime.InteropServices;
#endif
using Microsoft.Toolkit.HighPerformance.Extensions;
using Microsoft.Toolkit.HighPerformance.Helpers.Internals;
using Microsoft.Toolkit.HighPerformance.Memory.Internals;

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

@ -76,7 +76,16 @@ namespace Microsoft.Toolkit.HighPerformance.Enumerables
{
this.start = newEnd;
int index = this.span.Slice(newEnd).IndexOf(this.separator);
// We need to call this extension explicitly or the extension method resolution rules for the C# compiler
// will end up picking Microsoft.Toolkit.HighPerformance.ReadOnlySpanExtensions.IndexOf instead, even
// though the latter takes the parameter via a readonly reference. This is because the "in" modifier is
// implicit, which makes the signature compatible, and because extension methods are matched in such a
// way that methods "closest" to where they're used are preferred. Since this type shares the same root
// namespace, this makes that extension a better match, so that it overrides the MemoryExtensions one.
// This is not a problem for consumers of this package, as their code would be outside of the
// Microsoft.Toolkit.HighPerformance namespace, so both extensions would be "equally distant", so that
// when they're both in scope it will be possible to choose which one to use by adding an explicit "in".
int index = System.MemoryExtensions.IndexOf(this.span.Slice(newEnd), this.separator);
// Extract the current subsequence
if (index >= 0)

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

@ -8,7 +8,6 @@ using System.Runtime.CompilerServices;
#if SPAN_RUNTIME_SUPPORT
using System.Runtime.InteropServices;
#endif
using Microsoft.Toolkit.HighPerformance.Extensions;
using Microsoft.Toolkit.HighPerformance.Helpers.Internals;
#if SPAN_RUNTIME_SUPPORT
using Microsoft.Toolkit.HighPerformance.Memory.Internals;

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

@ -9,10 +9,13 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
#endif
using Microsoft.Toolkit.HighPerformance.Enumerables;
#if !NETCORE_RUNTIME && !NET5_0
using Microsoft.Toolkit.HighPerformance.Helpers;
#endif
using Microsoft.Toolkit.HighPerformance.Helpers.Internals;
using RuntimeHelpers = Microsoft.Toolkit.HighPerformance.Helpers.Internals.RuntimeHelpers;
namespace Microsoft.Toolkit.HighPerformance.Extensions
namespace Microsoft.Toolkit.HighPerformance
{
/// <summary>
/// Helpers for working with the <see cref="Array"/> type.
@ -40,7 +43,7 @@ namespace Microsoft.Toolkit.HighPerformance.Extensions
#else
IntPtr offset = RuntimeHelpers.GetArrayDataByteOffset<T>();
return ref array.DangerousGetObjectDataReferenceAt<T>(offset);
return ref ObjectMarshal.DangerousGetObjectDataReferenceAt<T>(array, offset);
#endif
}
@ -69,7 +72,7 @@ namespace Microsoft.Toolkit.HighPerformance.Extensions
return ref ri;
#else
IntPtr offset = RuntimeHelpers.GetArrayDataByteOffset<T>();
ref T r0 = ref array.DangerousGetObjectDataReferenceAt<T>(offset);
ref T r0 = ref ObjectMarshal.DangerousGetObjectDataReferenceAt<T>(array, offset);
ref T ri = ref Unsafe.Add(ref r0, (nint)(uint)i);
return ref ri;

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

@ -10,10 +10,11 @@ using System.Runtime.InteropServices;
using Microsoft.Toolkit.HighPerformance.Buffers.Internals;
#endif
using Microsoft.Toolkit.HighPerformance.Enumerables;
using Microsoft.Toolkit.HighPerformance.Helpers;
using Microsoft.Toolkit.HighPerformance.Helpers.Internals;
using RuntimeHelpers = Microsoft.Toolkit.HighPerformance.Helpers.Internals.RuntimeHelpers;
namespace Microsoft.Toolkit.HighPerformance.Extensions
namespace Microsoft.Toolkit.HighPerformance
{
/// <summary>
/// Helpers for working with the <see cref="Array"/> type.
@ -39,7 +40,7 @@ namespace Microsoft.Toolkit.HighPerformance.Extensions
#else
IntPtr offset = RuntimeHelpers.GetArray2DDataByteOffset<T>();
return ref array.DangerousGetObjectDataReferenceAt<T>(offset);
return ref ObjectMarshal.DangerousGetObjectDataReferenceAt<T>(array, offset);
#endif
}
@ -72,7 +73,7 @@ namespace Microsoft.Toolkit.HighPerformance.Extensions
int width = array.GetLength(1);
nint index = ((nint)(uint)i * (nint)(uint)width) + (nint)(uint)j;
IntPtr offset = RuntimeHelpers.GetArray2DDataByteOffset<T>();
ref T r0 = ref array.DangerousGetObjectDataReferenceAt<T>(offset);
ref T r0 = ref ObjectMarshal.DangerousGetObjectDataReferenceAt<T>(array, offset);
ref T ri = ref Unsafe.Add(ref r0, index);
return ref ri;
@ -137,7 +138,7 @@ namespace Microsoft.Toolkit.HighPerformance.Extensions
return new RefEnumerable<T>(ref r0, width, 1);
#else
ref T r0 = ref array.DangerousGetReferenceAt(row, 0);
IntPtr offset = array.DangerousGetObjectDataByteOffset(ref r0);
IntPtr offset = ObjectMarshal.DangerousGetObjectDataByteOffset(array, ref r0);
return new RefEnumerable<T>(array, offset, width, 1);
#endif
@ -191,7 +192,7 @@ namespace Microsoft.Toolkit.HighPerformance.Extensions
return new RefEnumerable<T>(ref r0, height, width);
#else
ref T r0 = ref array.DangerousGetReferenceAt(0, column);
IntPtr offset = array.DangerousGetObjectDataByteOffset(ref r0);
IntPtr offset = ObjectMarshal.DangerousGetObjectDataByteOffset(array, ref r0);
return new RefEnumerable<T>(array, offset, height, width);
#endif
@ -324,7 +325,7 @@ namespace Microsoft.Toolkit.HighPerformance.Extensions
}
ref T r0 = ref array.DangerousGetReferenceAt(row, 0);
IntPtr offset = array.DangerousGetObjectDataByteOffset(ref r0);
IntPtr offset = ObjectMarshal.DangerousGetObjectDataByteOffset(array, ref r0);
return new RawObjectMemoryManager<T>(array, offset, array.GetLength(1)).Memory;
}

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

@ -5,6 +5,7 @@
using System;
using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
using Microsoft.Toolkit.HighPerformance.Helpers;
#if SPAN_RUNTIME_SUPPORT
using System.Runtime.InteropServices;
using Microsoft.Toolkit.HighPerformance.Buffers.Internals;
@ -12,7 +13,7 @@ using Microsoft.Toolkit.HighPerformance.Buffers.Internals;
using Microsoft.Toolkit.HighPerformance.Helpers.Internals;
using RuntimeHelpers = Microsoft.Toolkit.HighPerformance.Helpers.Internals.RuntimeHelpers;
namespace Microsoft.Toolkit.HighPerformance.Extensions
namespace Microsoft.Toolkit.HighPerformance
{
/// <summary>
/// Helpers for working with the <see cref="Array"/> type.
@ -38,7 +39,7 @@ namespace Microsoft.Toolkit.HighPerformance.Extensions
#else
IntPtr offset = RuntimeHelpers.GetArray3DDataByteOffset<T>();
return ref array.DangerousGetObjectDataReferenceAt<T>(offset);
return ref ObjectMarshal.DangerousGetObjectDataReferenceAt<T>(array, offset);
#endif
}
@ -78,7 +79,7 @@ namespace Microsoft.Toolkit.HighPerformance.Extensions
((nint)(uint)i * (nint)(uint)height * (nint)(uint)width) +
((nint)(uint)j * (nint)(uint)width) + (nint)(uint)k;
IntPtr offset = RuntimeHelpers.GetArray3DDataByteOffset<T>();
ref T r0 = ref array.DangerousGetObjectDataReferenceAt<T>(offset);
ref T r0 = ref ObjectMarshal.DangerousGetObjectDataReferenceAt<T>(array, offset);
ref T ri = ref Unsafe.Add(ref r0, index);
return ref ri;
@ -212,7 +213,7 @@ namespace Microsoft.Toolkit.HighPerformance.Extensions
}
ref T r0 = ref array.DangerousGetReferenceAt(depth, 0, 0);
IntPtr offset = array.DangerousGetObjectDataByteOffset(ref r0);
IntPtr offset = ObjectMarshal.DangerousGetObjectDataByteOffset(array, ref r0);
int length = checked(array.GetLength(1) * array.GetLength(2));
return new RawObjectMemoryManager<T>(array, offset, length).Memory;

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

@ -7,9 +7,8 @@ using System.IO;
using System.Runtime.CompilerServices;
using Microsoft.Toolkit.HighPerformance.Buffers;
using Microsoft.Toolkit.HighPerformance.Streams;
using Microsoft.Toolkit.HighPerformance.Streams.Sources;
namespace Microsoft.Toolkit.HighPerformance.Extensions
namespace Microsoft.Toolkit.HighPerformance
{
/// <summary>
/// Helpers for working with the <see cref="ArrayPoolBufferWriter{T}"/> type.

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

@ -5,7 +5,7 @@
using System;
using System.Buffers;
namespace Microsoft.Toolkit.HighPerformance.Extensions
namespace Microsoft.Toolkit.HighPerformance
{
/// <summary>
/// Helpers for working with the <see cref="ArrayPool{T}"/> type.

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

@ -6,7 +6,7 @@ using System;
using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
namespace Microsoft.Toolkit.HighPerformance.Extensions
namespace Microsoft.Toolkit.HighPerformance
{
/// <summary>
/// Helpers for working with the <see cref="bool"/> type.
@ -33,20 +33,6 @@ namespace Microsoft.Toolkit.HighPerformance.Extensions
return *(byte*)&copy;
}
/// <summary>
/// Converts the given <see cref="bool"/> value into an <see cref="int"/>.
/// </summary>
/// <param name="flag">The input value to convert.</param>
/// <returns>1 if <paramref name="flag"/> is <see langword="true"/>, 0 otherwise.</returns>
/// <remarks>This method does not contain branching instructions.</remarks>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[Obsolete("Use ToByte instead.")]
public static unsafe int ToInt(this bool flag)
{
return *(byte*)&flag;
}
/// <summary>
/// Converts the given <see cref="bool"/> value to an <see cref="int"/> mask with
/// all bits representing the value of the input flag (either 0xFFFFFFFF or 0x00000000).

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

@ -8,7 +8,7 @@ using System;
using System.Runtime.CompilerServices;
using Microsoft.Toolkit.HighPerformance.Helpers;
namespace Microsoft.Toolkit.HighPerformance.Extensions
namespace Microsoft.Toolkit.HighPerformance
{
/// <summary>
/// Helpers for working with the <see cref="HashCode"/> type.

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

@ -10,9 +10,8 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Microsoft.Toolkit.HighPerformance.Buffers;
using Microsoft.Toolkit.HighPerformance.Streams;
using Microsoft.Toolkit.HighPerformance.Streams.Sources;
namespace Microsoft.Toolkit.HighPerformance.Extensions
namespace Microsoft.Toolkit.HighPerformance
{
/// <summary>
/// Helpers for working with the <see cref="IBufferWriter{T}"/> type.

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

@ -9,7 +9,7 @@ using System.IO;
using System.Runtime.CompilerServices;
using MemoryStream = Microsoft.Toolkit.HighPerformance.Streams.MemoryStream;
namespace Microsoft.Toolkit.HighPerformance.Extensions
namespace Microsoft.Toolkit.HighPerformance
{
/// <summary>
/// Helpers for working with the <see cref="IMemoryOwner{T}"/> type.

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

@ -10,7 +10,7 @@ using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Microsoft.Toolkit.HighPerformance.Extensions
namespace Microsoft.Toolkit.HighPerformance
{
/// <summary>
/// Helpers for working with the <see cref="List{T}"/> type.

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

@ -9,7 +9,7 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using MemoryStream = Microsoft.Toolkit.HighPerformance.Streams.MemoryStream;
namespace Microsoft.Toolkit.HighPerformance.Extensions
namespace Microsoft.Toolkit.HighPerformance
{
/// <summary>
/// Helpers for working with the <see cref="Memory{T}"/> type.

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

@ -12,7 +12,7 @@ using Microsoft.Toolkit.HighPerformance.Buffers.Internals;
using Microsoft.Toolkit.HighPerformance.Buffers.Internals.Interfaces;
using MemoryStream = Microsoft.Toolkit.HighPerformance.Streams.MemoryStream;
namespace Microsoft.Toolkit.HighPerformance.Extensions
namespace Microsoft.Toolkit.HighPerformance
{
/// <summary>
/// Helpers for working with the <see cref="ReadOnlyMemory{T}"/> type.

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

@ -9,7 +9,7 @@ using System.Runtime.InteropServices;
using Microsoft.Toolkit.HighPerformance.Enumerables;
using Microsoft.Toolkit.HighPerformance.Helpers.Internals;
namespace Microsoft.Toolkit.HighPerformance.Extensions
namespace Microsoft.Toolkit.HighPerformance
{
/// <summary>
/// Helpers for working with the <see cref="ReadOnlySpan{T}"/> type.

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

@ -9,7 +9,7 @@ using System.Runtime.InteropServices;
using Microsoft.Toolkit.HighPerformance.Enumerables;
using Microsoft.Toolkit.HighPerformance.Helpers.Internals;
namespace Microsoft.Toolkit.HighPerformance.Extensions
namespace Microsoft.Toolkit.HighPerformance
{
/// <summary>
/// Helpers for working with the <see cref="Span{T}"/> type.

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

@ -6,7 +6,7 @@ using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Threading;
namespace Microsoft.Toolkit.HighPerformance.Extensions
namespace Microsoft.Toolkit.HighPerformance
{
/// <summary>
/// Helpers for working with the <see cref="SpinLock"/> type.

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

@ -12,7 +12,7 @@ using System.Threading;
using System.Threading.Tasks;
#endif
namespace Microsoft.Toolkit.HighPerformance.Extensions
namespace Microsoft.Toolkit.HighPerformance
{
/// <summary>
/// Helpers for working with the <see cref="Stream"/> type.

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

@ -11,7 +11,7 @@ using System.Runtime.InteropServices;
using Microsoft.Toolkit.HighPerformance.Enumerables;
using Microsoft.Toolkit.HighPerformance.Helpers.Internals;
namespace Microsoft.Toolkit.HighPerformance.Extensions
namespace Microsoft.Toolkit.HighPerformance
{
/// <summary>
/// Helpers for working with the <see cref="string"/> type.

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

@ -13,7 +13,6 @@ using System.Diagnostics.Contracts;
using System.Reflection;
#endif
using System.Runtime.CompilerServices;
using Microsoft.Toolkit.HighPerformance.Extensions;
namespace Microsoft.Toolkit.HighPerformance.Helpers.Internals
{
@ -152,7 +151,7 @@ namespace Microsoft.Toolkit.HighPerformance.Helpers.Internals
return (IntPtr)Unsafe.AsPointer(ref data);
}
return obj.DangerousGetObjectDataByteOffset(ref data);
return ObjectMarshal.DangerousGetObjectDataByteOffset(obj, ref data);
}
/// <summary>
@ -174,7 +173,7 @@ namespace Microsoft.Toolkit.HighPerformance.Helpers.Internals
return ref Unsafe.AsRef<T>((void*)offset);
}
return ref obj.DangerousGetObjectDataReferenceAt<T>(offset);
return ref ObjectMarshal.DangerousGetObjectDataReferenceAt<T>(obj, offset);
}
/// <summary>
@ -274,7 +273,7 @@ namespace Microsoft.Toolkit.HighPerformance.Helpers.Internals
{
var array = new T[1];
return array.DangerousGetObjectDataByteOffset(ref array[0]);
return ObjectMarshal.DangerousGetObjectDataByteOffset(array, ref array[0]);
}
/// <summary>
@ -286,7 +285,7 @@ namespace Microsoft.Toolkit.HighPerformance.Helpers.Internals
{
var array = new T[1, 1];
return array.DangerousGetObjectDataByteOffset(ref array[0, 0]);
return ObjectMarshal.DangerousGetObjectDataByteOffset(array, ref array[0, 0]);
}
/// <summary>
@ -298,7 +297,7 @@ namespace Microsoft.Toolkit.HighPerformance.Helpers.Internals
{
var array = new T[1, 1, 1];
return array.DangerousGetObjectDataByteOffset(ref array[0, 0, 0]);
return ObjectMarshal.DangerousGetObjectDataByteOffset(array, ref array[0, 0, 0]);
}
}
}

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

@ -6,7 +6,6 @@ using System;
using System.Diagnostics.Contracts;
using System.Numerics;
using System.Runtime.CompilerServices;
using Microsoft.Toolkit.HighPerformance.Extensions;
namespace Microsoft.Toolkit.HighPerformance.Helpers.Internals
{

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

@ -7,12 +7,12 @@ using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Microsoft.Toolkit.HighPerformance.Extensions
namespace Microsoft.Toolkit.HighPerformance.Helpers
{
/// <summary>
/// Helpers for working with <see cref="object"/> instances.
/// </summary>
public static class ObjectExtensions
public static class ObjectMarshal
{
/// <summary>
/// Calculates the byte offset to a specific field within a given <see cref="object"/>.
@ -29,7 +29,7 @@ namespace Microsoft.Toolkit.HighPerformance.Extensions
/// </remarks>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static IntPtr DangerousGetObjectDataByteOffset<T>(this object obj, ref T data)
public static IntPtr DangerousGetObjectDataByteOffset<T>(object obj, ref T data)
{
var rawObj = Unsafe.As<RawObjectData>(obj)!;
ref byte r0 = ref rawObj.Data;
@ -53,7 +53,7 @@ namespace Microsoft.Toolkit.HighPerformance.Extensions
/// </remarks>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref T DangerousGetObjectDataReferenceAt<T>(this object obj, IntPtr offset)
public static ref T DangerousGetObjectDataReferenceAt<T>(object obj, IntPtr offset)
{
var rawObj = Unsafe.As<RawObjectData>(obj)!;
ref byte r0 = ref rawObj.Data;
@ -97,7 +97,7 @@ namespace Microsoft.Toolkit.HighPerformance.Extensions
/// <remarks>
/// This extension behaves just like the following method:
/// <code>
/// public static bool TryUnbox&lt;T>(this object obj, out T value)
/// public static bool TryUnbox&lt;T>(object obj, out T value)
/// {
/// if (obj is T)
/// {
@ -139,7 +139,7 @@ namespace Microsoft.Toolkit.HighPerformance.Extensions
/// <exception cref="InvalidCastException">Thrown when <paramref name="obj"/> is not of type <typeparamref name="T"/>.</exception>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref T DangerousUnbox<T>(this object obj)
public static ref T DangerousUnbox<T>(object obj)
where T : struct
{
return ref Unsafe.Unbox<T>(obj);

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

@ -12,7 +12,7 @@ using System.Runtime.InteropServices;
#if SPAN_RUNTIME_SUPPORT
using Microsoft.Toolkit.HighPerformance.Buffers.Internals;
#endif
using Microsoft.Toolkit.HighPerformance.Extensions;
using Microsoft.Toolkit.HighPerformance.Helpers;
using Microsoft.Toolkit.HighPerformance.Memory.Internals;
using Microsoft.Toolkit.HighPerformance.Memory.Views;
using static Microsoft.Toolkit.HighPerformance.Helpers.Internals.RuntimeHelpers;
@ -129,7 +129,7 @@ namespace Microsoft.Toolkit.HighPerformance
}
this.instance = array;
this.offset = array.DangerousGetObjectDataByteOffset(ref array.DangerousGetReferenceAt(offset));
this.offset = ObjectMarshal.DangerousGetObjectDataByteOffset(array, ref array.DangerousGetReferenceAt(offset));
this.height = height;
this.width = width;
this.pitch = pitch;
@ -222,7 +222,7 @@ namespace Microsoft.Toolkit.HighPerformance
}
this.instance = array;
this.offset = array.DangerousGetObjectDataByteOffset(ref array.DangerousGetReferenceAt(row, column));
this.offset = ObjectMarshal.DangerousGetObjectDataByteOffset(array, ref array.DangerousGetReferenceAt(row, column));
this.height = height;
this.width = width;
this.pitch = columns - width;
@ -250,7 +250,7 @@ namespace Microsoft.Toolkit.HighPerformance
}
this.instance = array;
this.offset = array.DangerousGetObjectDataByteOffset(ref array.DangerousGetReferenceAt(depth, 0, 0));
this.offset = ObjectMarshal.DangerousGetObjectDataByteOffset(array, ref array.DangerousGetReferenceAt(depth, 0, 0));
this.height = array.GetLength(1);
this.width = array.GetLength(2);
this.pitch = 0;
@ -306,7 +306,7 @@ namespace Microsoft.Toolkit.HighPerformance
}
this.instance = array;
this.offset = array.DangerousGetObjectDataByteOffset(ref array.DangerousGetReferenceAt(depth, row, column));
this.offset = ObjectMarshal.DangerousGetObjectDataByteOffset(array, ref array.DangerousGetReferenceAt(depth, row, column));
this.height = height;
this.width = width;
this.pitch = columns - width;
@ -465,7 +465,7 @@ namespace Microsoft.Toolkit.HighPerformance
ref char r0 = ref text.DangerousGetReferenceAt(textStart + offset);
this.instance = text;
this.offset = text.DangerousGetObjectDataByteOffset(ref r0);
this.offset = ObjectMarshal.DangerousGetObjectDataByteOffset(text, ref r0);
}
else if (MemoryMarshal.TryGetArray(memory, out ArraySegment<T> segment))
{
@ -477,7 +477,7 @@ namespace Microsoft.Toolkit.HighPerformance
T[] array = segment.Array!;
this.instance = array;
this.offset = array.DangerousGetObjectDataByteOffset(ref array.DangerousGetReferenceAt(segment.Offset + offset));
this.offset = ObjectMarshal.DangerousGetObjectDataByteOffset(array, ref array.DangerousGetReferenceAt(segment.Offset + offset));
}
else if (MemoryMarshal.TryGetMemoryManager<T, MemoryManager<T>>(memory, out var memoryManager, out int memoryManagerStart, out _))
{
@ -549,7 +549,7 @@ namespace Microsoft.Toolkit.HighPerformance
OverflowHelper.EnsureIsInNativeIntRange(height, width, pitch);
IntPtr offset = instance.DangerousGetObjectDataByteOffset(ref value);
IntPtr offset = ObjectMarshal.DangerousGetObjectDataByteOffset(instance, ref value);
return new Memory2D<T>(instance, offset, height, width, pitch);
}
@ -615,7 +615,7 @@ namespace Microsoft.Toolkit.HighPerformance
}
else
{
ref T r0 = ref this.instance.DangerousGetObjectDataReferenceAt<T>(this.offset);
ref T r0 = ref ObjectMarshal.DangerousGetObjectDataReferenceAt<T>(this.instance, this.offset);
return new Span2D<T>(ref r0, this.height, this.width, this.pitch);
}
@ -749,7 +749,7 @@ namespace Microsoft.Toolkit.HighPerformance
GCHandle handle = GCHandle.Alloc(this.instance, GCHandleType.Pinned);
void* pointer = Unsafe.AsPointer(ref this.instance.DangerousGetObjectDataReferenceAt<T>(this.offset));
void* pointer = Unsafe.AsPointer(ref ObjectMarshal.DangerousGetObjectDataReferenceAt<T>(this.instance, this.offset));
return new MemoryHandle(pointer, handle);
}
@ -775,7 +775,7 @@ namespace Microsoft.Toolkit.HighPerformance
else if (typeof(T) == typeof(char) && this.instance.GetType() == typeof(string))
{
string text = Unsafe.As<string>(this.instance)!;
int index = text.AsSpan().IndexOf(in text.DangerousGetObjectDataReferenceAt<char>(this.offset));
int index = text.AsSpan().IndexOf(in ObjectMarshal.DangerousGetObjectDataReferenceAt<char>(text, this.offset));
ReadOnlyMemory<char> temp = text.AsMemory(index, (int)Length);
// The string type could still be present if a user ends up creating a
@ -795,7 +795,7 @@ namespace Microsoft.Toolkit.HighPerformance
{
// If it's a T[] array, also handle the initial offset
T[] array = Unsafe.As<T[]>(this.instance)!;
int index = array.AsSpan().IndexOf(ref array.DangerousGetObjectDataReferenceAt<T>(this.offset));
int index = array.AsSpan().IndexOf(ref ObjectMarshal.DangerousGetObjectDataReferenceAt<T>(array, this.offset));
memory = array.AsMemory(index, this.height * this.width);
}

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

@ -12,7 +12,7 @@ using System.Runtime.InteropServices;
#if SPAN_RUNTIME_SUPPORT
using Microsoft.Toolkit.HighPerformance.Buffers.Internals;
#endif
using Microsoft.Toolkit.HighPerformance.Extensions;
using Microsoft.Toolkit.HighPerformance.Helpers;
using Microsoft.Toolkit.HighPerformance.Memory.Internals;
using Microsoft.Toolkit.HighPerformance.Memory.Views;
using static Microsoft.Toolkit.HighPerformance.Helpers.Internals.RuntimeHelpers;
@ -115,7 +115,7 @@ namespace Microsoft.Toolkit.HighPerformance
}
this.instance = text;
this.offset = text.DangerousGetObjectDataByteOffset(ref text.DangerousGetReferenceAt(offset));
this.offset = ObjectMarshal.DangerousGetObjectDataByteOffset(text, ref text.DangerousGetReferenceAt(offset));
this.height = height;
this.width = width;
this.pitch = pitch;
@ -182,7 +182,7 @@ namespace Microsoft.Toolkit.HighPerformance
}
this.instance = array;
this.offset = array.DangerousGetObjectDataByteOffset(ref array.DangerousGetReferenceAt(offset));
this.offset = ObjectMarshal.DangerousGetObjectDataByteOffset(array, ref array.DangerousGetReferenceAt(offset));
this.height = height;
this.width = width;
this.pitch = pitch;
@ -259,7 +259,7 @@ namespace Microsoft.Toolkit.HighPerformance
}
this.instance = array;
this.offset = array.DangerousGetObjectDataByteOffset(ref array.DangerousGetReferenceAt(row, column));
this.offset = ObjectMarshal.DangerousGetObjectDataByteOffset(array, ref array.DangerousGetReferenceAt(row, column));
this.height = height;
this.width = width;
this.pitch = columns - width;
@ -279,7 +279,7 @@ namespace Microsoft.Toolkit.HighPerformance
}
this.instance = array;
this.offset = array.DangerousGetObjectDataByteOffset(ref array.DangerousGetReferenceAt(depth, 0, 0));
this.offset = ObjectMarshal.DangerousGetObjectDataByteOffset(array, ref array.DangerousGetReferenceAt(depth, 0, 0));
this.height = array.GetLength(1);
this.width = array.GetLength(2);
this.pitch = 0;
@ -327,7 +327,7 @@ namespace Microsoft.Toolkit.HighPerformance
}
this.instance = array;
this.offset = array.DangerousGetObjectDataByteOffset(ref array.DangerousGetReferenceAt(depth, row, column));
this.offset = ObjectMarshal.DangerousGetObjectDataByteOffset(array, ref array.DangerousGetReferenceAt(depth, row, column));
this.height = height;
this.width = width;
this.pitch = columns - width;
@ -484,14 +484,14 @@ namespace Microsoft.Toolkit.HighPerformance
ref char r0 = ref text.DangerousGetReferenceAt(textStart + offset);
this.instance = text;
this.offset = text.DangerousGetObjectDataByteOffset(ref r0);
this.offset = ObjectMarshal.DangerousGetObjectDataByteOffset(text, ref r0);
}
else if (MemoryMarshal.TryGetArray(memory, out ArraySegment<T> segment))
{
T[] array = segment.Array!;
this.instance = array;
this.offset = array.DangerousGetObjectDataByteOffset(ref array.DangerousGetReferenceAt(segment.Offset + offset));
this.offset = ObjectMarshal.DangerousGetObjectDataByteOffset(array, ref array.DangerousGetReferenceAt(segment.Offset + offset));
}
else if (MemoryMarshal.TryGetMemoryManager<T, MemoryManager<T>>(memory, out var memoryManager, out int memoryManagerStart, out _))
{
@ -563,7 +563,7 @@ namespace Microsoft.Toolkit.HighPerformance
OverflowHelper.EnsureIsInNativeIntRange(height, width, pitch);
IntPtr offset = instance.DangerousGetObjectDataByteOffset(ref value);
IntPtr offset = ObjectMarshal.DangerousGetObjectDataByteOffset(instance, ref value);
return new ReadOnlyMemory2D<T>(instance, offset, height, width, pitch);
}
@ -630,7 +630,7 @@ namespace Microsoft.Toolkit.HighPerformance
else
{
// This handles both arrays and strings
ref T r0 = ref this.instance.DangerousGetObjectDataReferenceAt<T>(this.offset);
ref T r0 = ref ObjectMarshal.DangerousGetObjectDataReferenceAt<T>(this.instance, this.offset);
return new ReadOnlySpan2D<T>(in r0, this.height, this.width, this.pitch);
}
@ -764,7 +764,7 @@ namespace Microsoft.Toolkit.HighPerformance
GCHandle handle = GCHandle.Alloc(this.instance, GCHandleType.Pinned);
void* pointer = Unsafe.AsPointer(ref this.instance.DangerousGetObjectDataReferenceAt<T>(this.offset));
void* pointer = Unsafe.AsPointer(ref ObjectMarshal.DangerousGetObjectDataReferenceAt<T>(this.instance, this.offset));
return new MemoryHandle(pointer, handle);
}
@ -797,7 +797,7 @@ namespace Microsoft.Toolkit.HighPerformance
// within the string), and the input reference, which we can get from the byte offset in use. The result
// is the character index which we can use to create the final Memory<char> instance.
string text = Unsafe.As<string>(this.instance)!;
int index = text.AsSpan().IndexOf(in text.DangerousGetObjectDataReferenceAt<char>(this.offset));
int index = text.AsSpan().IndexOf(in ObjectMarshal.DangerousGetObjectDataReferenceAt<char>(text, this.offset));
ReadOnlyMemory<char> temp = text.AsMemory(index, (int)Length);
memory = Unsafe.As<ReadOnlyMemory<char>, ReadOnlyMemory<T>>(ref temp);
@ -811,7 +811,7 @@ namespace Microsoft.Toolkit.HighPerformance
{
// If it's a T[] array, also handle the initial offset
T[] array = Unsafe.As<T[]>(this.instance)!;
int index = array.AsSpan().IndexOf(ref array.DangerousGetObjectDataReferenceAt<T>(this.offset));
int index = array.AsSpan().IndexOf(ref ObjectMarshal.DangerousGetObjectDataReferenceAt<T>(array, this.offset));
memory = array.AsMemory(index, this.height * this.width);
}

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

@ -8,7 +8,9 @@ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Microsoft.Toolkit.HighPerformance.Extensions;
#if !SPAN_RUNTIME_SUPPORT
using Microsoft.Toolkit.HighPerformance.Helpers;
#endif
using Microsoft.Toolkit.HighPerformance.Memory.Internals;
using Microsoft.Toolkit.HighPerformance.Memory.Views;
#if !SPAN_RUNTIME_SUPPORT
@ -210,7 +212,7 @@ namespace Microsoft.Toolkit.HighPerformance
this.span = MemoryMarshal.CreateReadOnlySpan(ref array.DangerousGetReferenceAt(offset), height);
#else
this.instance = array;
this.offset = array.DangerousGetObjectDataByteOffset(ref array.DangerousGetReferenceAt(offset));
this.offset = ObjectMarshal.DangerousGetObjectDataByteOffset(array, ref array.DangerousGetReferenceAt(offset));
this.height = height;
#endif
this.width = width;
@ -234,7 +236,7 @@ namespace Microsoft.Toolkit.HighPerformance
this.span = MemoryMarshal.CreateReadOnlySpan(ref array.DangerousGetReference(), array.GetLength(0));
#else
this.instance = array;
this.offset = array.DangerousGetObjectDataByteOffset(ref array.DangerousGetReferenceAt(0, 0));
this.offset = ObjectMarshal.DangerousGetObjectDataByteOffset(array, ref array.DangerousGetReferenceAt(0, 0));
this.height = array.GetLength(0);
#endif
this.width = this.stride = array.GetLength(1);
@ -294,7 +296,7 @@ namespace Microsoft.Toolkit.HighPerformance
this.span = MemoryMarshal.CreateReadOnlySpan(ref array.DangerousGetReferenceAt(row, column), height);
#else
this.instance = array;
this.offset = array.DangerousGetObjectDataByteOffset(ref array.DangerousGetReferenceAt(row, column));
this.offset = ObjectMarshal.DangerousGetObjectDataByteOffset(array, ref array.DangerousGetReferenceAt(row, column));
this.height = height;
#endif
this.width = width;
@ -318,7 +320,7 @@ namespace Microsoft.Toolkit.HighPerformance
this.span = MemoryMarshal.CreateReadOnlySpan(ref array.DangerousGetReferenceAt(depth, 0, 0), array.GetLength(1));
#else
this.instance = array;
this.offset = array.DangerousGetObjectDataByteOffset(ref array.DangerousGetReferenceAt(depth, 0, 0));
this.offset = ObjectMarshal.DangerousGetObjectDataByteOffset(array, ref array.DangerousGetReferenceAt(depth, 0, 0));
this.height = array.GetLength(1);
#endif
this.width = this.stride = array.GetLength(2);
@ -369,7 +371,7 @@ namespace Microsoft.Toolkit.HighPerformance
this.span = MemoryMarshal.CreateReadOnlySpan(ref array.DangerousGetReferenceAt(depth, row, column), height);
#else
this.instance = array;
this.offset = array.DangerousGetObjectDataByteOffset(ref array.DangerousGetReferenceAt(depth, row, column));
this.offset = ObjectMarshal.DangerousGetObjectDataByteOffset(array, ref array.DangerousGetReferenceAt(depth, row, column));
this.height = height;
#endif
this.width = width;

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

@ -8,7 +8,9 @@ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Microsoft.Toolkit.HighPerformance.Extensions;
#if !SPAN_RUNTIME_SUPPORT
using Microsoft.Toolkit.HighPerformance.Helpers;
#endif
using Microsoft.Toolkit.HighPerformance.Memory.Internals;
using Microsoft.Toolkit.HighPerformance.Memory.Views;
#if !SPAN_RUNTIME_SUPPORT
@ -249,7 +251,7 @@ namespace Microsoft.Toolkit.HighPerformance
this.span = MemoryMarshal.CreateSpan(ref array.DangerousGetReferenceAt(offset), height);
#else
this.Instance = array;
this.Offset = array.DangerousGetObjectDataByteOffset(ref array.DangerousGetReferenceAt(offset));
this.Offset = ObjectMarshal.DangerousGetObjectDataByteOffset(array, ref array.DangerousGetReferenceAt(offset));
this.height = height;
#endif
this.width = width;
@ -281,7 +283,7 @@ namespace Microsoft.Toolkit.HighPerformance
this.span = MemoryMarshal.CreateSpan(ref array.DangerousGetReference(), array.GetLength(0));
#else
this.Instance = array;
this.Offset = array.DangerousGetObjectDataByteOffset(ref array.DangerousGetReferenceAt(0, 0));
this.Offset = ObjectMarshal.DangerousGetObjectDataByteOffset(array, ref array.DangerousGetReferenceAt(0, 0));
this.height = array.GetLength(0);
#endif
this.width = this.Stride = array.GetLength(1);
@ -349,7 +351,7 @@ namespace Microsoft.Toolkit.HighPerformance
this.span = MemoryMarshal.CreateSpan(ref array.DangerousGetReferenceAt(row, column), height);
#else
this.Instance = array;
this.Offset = array.DangerousGetObjectDataByteOffset(ref array.DangerousGetReferenceAt(row, column));
this.Offset = ObjectMarshal.DangerousGetObjectDataByteOffset(array, ref array.DangerousGetReferenceAt(row, column));
this.height = height;
#endif
this.width = width;
@ -381,7 +383,7 @@ namespace Microsoft.Toolkit.HighPerformance
this.span = MemoryMarshal.CreateSpan(ref array.DangerousGetReferenceAt(depth, 0, 0), array.GetLength(1));
#else
this.Instance = array;
this.Offset = array.DangerousGetObjectDataByteOffset(ref array.DangerousGetReferenceAt(depth, 0, 0));
this.Offset = ObjectMarshal.DangerousGetObjectDataByteOffset(array, ref array.DangerousGetReferenceAt(depth, 0, 0));
this.height = array.GetLength(1);
#endif
this.width = this.Stride = array.GetLength(2);
@ -440,7 +442,7 @@ namespace Microsoft.Toolkit.HighPerformance
this.span = MemoryMarshal.CreateSpan(ref array.DangerousGetReferenceAt(depth, row, column), height);
#else
this.Instance = array;
this.Offset = array.DangerousGetObjectDataByteOffset(ref array.DangerousGetReferenceAt(depth, row, column));
this.Offset = ObjectMarshal.DangerousGetObjectDataByteOffset(array, ref array.DangerousGetReferenceAt(depth, row, column));
this.height = height;
#endif
this.width = width;

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

@ -7,7 +7,7 @@ using System.Runtime.CompilerServices;
#if SPAN_RUNTIME_SUPPORT
using System.Runtime.InteropServices;
#else
using Microsoft.Toolkit.HighPerformance.Extensions;
using Microsoft.Toolkit.HighPerformance.Helpers;
#endif
namespace Microsoft.Toolkit.HighPerformance
@ -98,7 +98,7 @@ namespace Microsoft.Toolkit.HighPerformance
public ReadOnlyRef(object owner, in T value)
{
this.owner = owner;
this.offset = owner.DangerousGetObjectDataByteOffset(ref Unsafe.AsRef(value));
this.offset = ObjectMarshal.DangerousGetObjectDataByteOffset(owner, ref Unsafe.AsRef(value));
}
/// <summary>
@ -107,7 +107,7 @@ namespace Microsoft.Toolkit.HighPerformance
public ref readonly T Value
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => ref this.owner.DangerousGetObjectDataReferenceAt<T>(this.offset);
get => ref ObjectMarshal.DangerousGetObjectDataReferenceAt<T>(this.owner, this.offset);
}
/// <summary>

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

@ -7,7 +7,7 @@ using System.Runtime.CompilerServices;
#if SPAN_RUNTIME_SUPPORT
using System.Runtime.InteropServices;
#else
using Microsoft.Toolkit.HighPerformance.Extensions;
using Microsoft.Toolkit.HighPerformance.Helpers;
#endif
namespace Microsoft.Toolkit.HighPerformance
@ -77,7 +77,7 @@ namespace Microsoft.Toolkit.HighPerformance
public Ref(object owner, ref T value)
{
Owner = owner;
Offset = owner.DangerousGetObjectDataByteOffset(ref value);
Offset = ObjectMarshal.DangerousGetObjectDataByteOffset(owner, ref value);
}
/// <summary>
@ -86,7 +86,7 @@ namespace Microsoft.Toolkit.HighPerformance
public ref T Value
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => ref Owner.DangerousGetObjectDataReferenceAt<T>(Offset);
get => ref ObjectMarshal.DangerousGetObjectDataReferenceAt<T>(Owner, Offset);
}
#endif

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

@ -7,7 +7,7 @@ using System.Buffers;
using System.Runtime.CompilerServices;
using Microsoft.Toolkit.HighPerformance.Buffers;
namespace Microsoft.Toolkit.HighPerformance.Streams.Sources
namespace Microsoft.Toolkit.HighPerformance.Streams
{
/// <summary>
/// An <see cref="IBufferWriter{T}"/> implementation wrapping an <see cref="ArrayPoolBufferWriter{T}"/> instance.

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

@ -6,7 +6,6 @@ using System;
using System.Runtime.CompilerServices;
#if SPAN_RUNTIME_SUPPORT
using System.Runtime.InteropServices;
using Microsoft.Toolkit.HighPerformance.Extensions;
#endif
namespace Microsoft.Toolkit.HighPerformance.Streams

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

@ -7,7 +7,7 @@ using System.Buffers;
using System.Runtime.CompilerServices;
using Microsoft.Toolkit.HighPerformance.Buffers;
namespace Microsoft.Toolkit.HighPerformance.Streams.Sources
namespace Microsoft.Toolkit.HighPerformance.Streams
{
/// <summary>
/// An <see cref="IBufferWriter{T}"/> implementation wrapping an <see cref="IBufferWriter{T}"/> instance.

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

@ -26,6 +26,18 @@ namespace Microsoft.Toolkit.Mvvm.ComponentModel
/// </summary>
private static readonly ConditionalWeakTable<Type, Action<object>> EntityValidatorMap = new();
/// <summary>
/// The <see cref="ConditionalWeakTable{TKey, TValue}"/> instance used to track display names for properties to validate.
/// </summary>
/// <remarks>
/// This is necessary because we want to reuse the same <see cref="ValidationContext"/> instance for all validations, but
/// with the same behavior with repsect to formatted names that new instances would have provided. The issue is that the
/// <see cref="ValidationContext.DisplayName"/> property is not refreshed when we set <see cref="ValidationContext.MemberName"/>,
/// so we need to replicate the same logic to retrieve the right display name for properties to validate and update that
/// property manually right before passing the context to <see cref="Validator"/> and proceed with the normal functionality.
/// </remarks>
private static readonly ConditionalWeakTable<Type, Dictionary<string, string>> DisplayNamesMap = new();
/// <summary>
/// The cached <see cref="PropertyChangedEventArgs"/> for <see cref="HasErrors"/>.
/// </summary>
@ -68,7 +80,7 @@ namespace Microsoft.Toolkit.Mvvm.ComponentModel
/// be used to validate all properties, which will reference the current instance.
/// </summary>
/// <param name="items">A set of key/value pairs to make available to consumers.</param>
protected ObservableValidator(IDictionary<object, object?> items)
protected ObservableValidator(IDictionary<object, object?>? items)
{
this.validationContext = new ValidationContext(this, items);
}
@ -80,7 +92,7 @@ namespace Microsoft.Toolkit.Mvvm.ComponentModel
/// </summary>
/// <param name="serviceProvider">An <see cref="IServiceProvider"/> instance to make available during validation.</param>
/// <param name="items">A set of key/value pairs to make available to consumers.</param>
protected ObservableValidator(IServiceProvider serviceProvider, IDictionary<object, object?> items)
protected ObservableValidator(IServiceProvider? serviceProvider, IDictionary<object, object?>? items)
{
this.validationContext = new ValidationContext(this, serviceProvider, items);
}
@ -541,6 +553,7 @@ namespace Microsoft.Toolkit.Mvvm.ComponentModel
// Validate the property, by adding new errors to the existing list
this.validationContext.MemberName = propertyName;
this.validationContext.DisplayName = GetDisplayNameForProperty(propertyName!);
bool isValid = Validator.TryValidateProperty(value, this.validationContext, propertyErrors);
@ -611,6 +624,7 @@ namespace Microsoft.Toolkit.Mvvm.ComponentModel
// Validate the property, by adding new errors to the local list
this.validationContext.MemberName = propertyName;
this.validationContext.DisplayName = GetDisplayNameForProperty(propertyName!);
bool isValid = Validator.TryValidateProperty(value, this.validationContext, localErrors);
@ -688,6 +702,36 @@ namespace Microsoft.Toolkit.Mvvm.ComponentModel
ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
}
/// <summary>
/// Gets the display name for a given property. It could be a custom name or just the property name.
/// </summary>
/// <param name="propertyName">The target property name being validated.</param>
/// <returns>The display name for the property.</returns>
private string GetDisplayNameForProperty(string propertyName)
{
static Dictionary<string, string> GetDisplayNames(Type type)
{
Dictionary<string, string> displayNames = new();
foreach (PropertyInfo property in type.GetProperties(BindingFlags.Instance | BindingFlags.Public))
{
if (property.GetCustomAttribute<DisplayAttribute>() is DisplayAttribute attribute &&
attribute.GetName() is string displayName)
{
displayNames.Add(property.Name, displayName);
}
}
return displayNames;
}
// This method replicates the logic of DisplayName and GetDisplayName from the
// ValidationContext class. See the original source in the BCL for more details.
DisplayNamesMap.GetValue(GetType(), static t => GetDisplayNames(t)).TryGetValue(propertyName, out string? displayName);
return displayName ?? propertyName;
}
#pragma warning disable SA1204
/// <summary>
/// Throws an <see cref="ArgumentNullException"/> when a property name given as input is <see langword="null"/>.

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

@ -132,7 +132,7 @@ namespace Microsoft.Toolkit.Mvvm.Messaging
}
// Get or compute the registration methods for the current recipient type.
// As in Microsoft.Toolkit.Extensions.TypeExtensions.ToTypeString, we use a lambda
// As in Microsoft.Toolkit.Diagnostics.TypeExtensions.ToTypeString, we use a lambda
// expression instead of a method group expression to leverage the statically initialized
// delegate and avoid repeated allocations for each invocation of this method.
// For more info on this, see the related issue at https://github.com/dotnet/roslyn/issues/5835.

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

@ -1,19 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<Title>Windows Community Toolkit .NET Standard Parsers</Title>
<Description>
This .NET standard library contains various parsers
Markdown: Allows you to parse a Markdown String into a Markdown Document, and then Render it with a Markdown Renderer.
</Description>
<PackageTags>UWP Toolkit Windows Parsers Parsing Markdown</PackageTags>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Microsoft.Toolkit\Microsoft.Toolkit.csproj" />
</ItemGroup>
</Project>

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

@ -1,27 +0,0 @@
// 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.
namespace Microsoft.Toolkit.Services.Core
{
/// <summary>
/// AuthenticationResult class, parameters: ResponseErrorDetail(uint), ResponseData(string) and ResponseStatus(AuthenticationResultStatus)
/// </summary>
public class AuthenticationResult
{
/// <summary>
/// Gets or sets the authentication error detail
/// </summary>
public uint ResponseErrorDetail { get; set; }
/// <summary>
/// Gets or sets the authentication result data
/// </summary>
public string ResponseData { get; set; }
/// <summary>
/// Gets or sets the authentication status, could be UserCancel, ErrorHttp and Success.
/// </summary>
public AuthenticationResultStatus ResponseStatus { get; set; }
}
}

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

@ -1,27 +0,0 @@
// 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.
namespace Microsoft.Toolkit.Services.Core
{
/// <summary>
/// Contains the status of the authentication operation
/// </summary>
public enum AuthenticationResultStatus
{
/// <summary>
/// The operation succeeded, and the response data is available.
/// </summary>
Success,
/// <summary>
/// The operation was canceled by the user
/// </summary>
UserCancel,
/// <summary>
/// The operation failed because a specific HTTP error was returned, for example 404
/// </summary>
ErrorHttp
}
}

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

@ -1,91 +0,0 @@
// 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;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
namespace Microsoft.Toolkit.Services
{
/// <summary>
/// Base class for data providers in this library.
/// </summary>
/// <typeparam name="TConfig">Query configuration type for given provider.</typeparam>
public abstract class DataProviderBase<TConfig>
{
/// <summary>
/// Initializes a new instance of the <see cref="DataProviderBase{TConfig}"/> class.
/// </summary>
public DataProviderBase()
{
}
/// <summary>
/// Load data from provider endpoint.
/// </summary>
/// <typeparam name="TSchema">Strong typed object to parse the response items into.</typeparam>
/// <param name="config">Query configuration.</param>
/// <param name="maxRecords">Upper record limit.</param>
/// <param name="pageIndex">The zero-based index of the page that corresponds to the items to retrieve.</param>
/// <param name="parser">Parser to use for results.</param>
/// <returns>Strong typed list of results.</returns>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an async method, so nesting generic types is necessary.")]
public async Task<IEnumerable<TSchema>> LoadDataAsync<TSchema>(TConfig config, int maxRecords, int pageIndex, Parsers.IParser<TSchema> parser)
where TSchema : Parsers.SchemaBase
{
if (config == null)
{
throw new ConfigNullException();
}
if (parser == null)
{
throw new ParserNullException();
}
ValidateConfig(config);
var result = await GetDataAsync(config, maxRecords, pageIndex, parser);
if (result != null)
{
return result
.Take(maxRecords)
.ToList();
}
return Array.Empty<TSchema>();
}
private static HttpClient httpClient;
/// <summary>
/// Gets or sets static instance of HttpClient.
/// </summary>
public static HttpClient HttpClient
{
get { return httpClient ?? (httpClient = new HttpClient()); }
set { httpClient = value; }
}
/// <summary>
/// Derived classes will have to implement this method to return provider data
/// </summary>
/// <param name="config">Configuration to use</param>
/// <param name="maxRecords">Maximum number of records to return</param>
/// <param name="pageIndex">The zero-based index of the page that corresponds to the items to retrieve.</param>
/// <param name="parser">Parser to use</param>
/// <typeparam name="TSchema">Schema defining data returned</typeparam>
/// <returns>List of data</returns>
protected abstract Task<IEnumerable<TSchema>> GetDataAsync<TSchema>(TConfig config, int maxRecords, int pageIndex, Parsers.IParser<TSchema> parser)
where TSchema : Parsers.SchemaBase;
/// <summary>
/// Method provided by derived class to validate specified configuration
/// </summary>
/// <param name="config">Configuration to validate</param>
protected abstract void ValidateConfig(TConfig config);
}
}

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

@ -1,37 +0,0 @@
// 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.Threading.Tasks;
namespace Microsoft.Toolkit.Services
{
/// <summary>
/// Base class for data providers in this library.
/// </summary>
/// <typeparam name="TConfig">Strong typed query configuration object.</typeparam>
/// <typeparam name="TSchema">Strong typed object to parse the response items into.</typeparam>
public abstract class DataProviderBase<TConfig, TSchema> : DataProviderBase<TConfig>
where TSchema : Parsers.SchemaBase
{
/// <summary>
/// Load data from provider endpoint.
/// </summary>
/// <param name="config">Query configuration.</param>
/// <param name="maxRecords">Upper record limit.</param>
/// <param name="pageIndex">The zero-based index of the page that corresponds to the items to retrieve.</param>
/// <returns>List of strong typed objects.</returns>
public Task<IEnumerable<TSchema>> LoadDataAsync(TConfig config, int maxRecords = 20, int pageIndex = 0)
{
return LoadDataAsync(config, maxRecords, pageIndex, GetDefaultParser(config));
}
/// <summary>
/// Default parser abstract method.
/// </summary>
/// <param name="config">Query configuration object.</param>
/// <returns>Strong typed default parser.</returns>
protected abstract Parsers.IParser<TSchema> GetDefaultParser(TConfig config);
}
}

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

@ -1,35 +0,0 @@
// 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;
using System.Reflection;
namespace Microsoft.Toolkit.Services
{
/// <summary>
/// This class offers general purpose methods.
/// </summary>
internal static class ExtensionMethods
{
/// <summary>
/// Converts between enumeration value and string value.
/// </summary>
/// <param name="value">Enumeration.</param>
/// <returns>Returns string value.</returns>
private static string GetStringValue(Enum value)
{
string output = null;
Type type = value.GetType();
FieldInfo fi = type.GetRuntimeField(value.ToString());
Parsers.Core.StringValueAttribute[] attrs = fi.GetCustomAttributes(typeof(Parsers.Core.StringValueAttribute), false) as Parsers.Core.StringValueAttribute[];
if (attrs != null && attrs.Length > 0)
{
output = attrs[0].Value;
}
return output;
}
}
}

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

@ -1,26 +0,0 @@
// 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;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Microsoft.Toolkit.Services.Core
{
/// <summary>
/// This gets an Uri value.
/// </summary>
public interface IAuthenticationBroker
{
/// <summary>
/// Returns the authentication status, it could be UserCancel, ErrorHttp and Success.
/// </summary>
/// <param name="requestUri"> Authorization base url</param>
/// <param name="callbackUri"> LinkedInOAuthTokens callbackUri</param>
/// <returns> Returns a status </returns>
Task<AuthenticationResult> Authenticate(Uri requestUri, Uri callbackUri);
}
}

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

@ -1,32 +0,0 @@
// 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.Threading.Tasks;
namespace Microsoft.Toolkit.Services
{
/// <summary>
/// Generic interface that all deployed service providers implement.
/// </summary>
/// <typeparam name="T">Reference to underlying data service provider.</typeparam>
/// <typeparam name="U">Strongly-typed schema for data returned in list query.</typeparam>
/// <typeparam name="V">Configuration type specifying query parameters.</typeparam>
public interface IDataService<T, U, V>
{
/// <summary>
/// Gets the underlying data service provider.
/// </summary>
T Provider { get; }
/// <summary>
/// Makes a request for a list of data from the given service provider.
/// </summary>
/// <param name="config">Describes the query on the list data request.</param>
/// <param name="maxRecords">Specifies an upper limit to the number of records returned.</param>
/// <param name="pageIndex">The zero-based index of the page that corresponds to the items to retrieve.</param>
/// <returns>Returns a strongly typed list of results from the service.</returns>
Task<List<U>> RequestAsync(V config, int maxRecords, int pageIndex = 0);
}
}

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

@ -1,32 +0,0 @@
// 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.
namespace Microsoft.Toolkit.Services.Core
{
/// <summary>
/// This interface gets a PasswordCredential, store the credential and remove the key.
/// </summary>
public interface IPasswordManager
{
/// <summary>
/// Gets the user credentials.
/// </summary>
/// <param name="key"> Receive the storage key user and the access token </param>
/// <returns> Returns user credential.</returns>
PasswordCredential Get(string key);
/// <summary>
/// Store users credential.
/// </summary>
/// <param name="resource"> Resource</param>
/// <param name="credential"> Username and password.</param>
void Store(string resource, PasswordCredential credential);
/// <summary>
/// Remove users credential.
/// </summary>
/// <param name="key"> Credential unique key</param>
void Remove(string key);
}
}

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

@ -1,21 +0,0 @@
// 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.
namespace Microsoft.Toolkit.Services.Core
{
/// <summary>
/// Provides platform specific logic to sign request for OAuth communication
/// </summary>
public interface ISignatureManager
{
/// <summary>
/// Generate request signature
/// </summary>
/// <param name="baseString">String to sign</param>
/// <param name="secret">Secret to use to sign</param>
/// <param name="append">If true append &amp; to the base string</param>
/// <returns>The signed baseString to use in the OAuth requests</returns>
string GetSignature(string baseString, string secret, bool append = false);
}
}

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

@ -1,29 +0,0 @@
// 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.Threading.Tasks;
namespace Microsoft.Toolkit.Services.Core
{
/// <summary>
/// This interface store the key value
/// </summary>
public interface IStorageManager
{
/// <summary>
/// Gets the key value
/// </summary>
/// <param name="key"> Token value </param>
/// <returns> Returns a string value</returns>
Task<string> GetAsync(string key);
/// <summary>
/// Sets the key value
/// </summary>
/// <param name="key"> Token key </param>
/// <param name="value"> String value </param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
Task SetAsync(string key, string value);
}
}

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

@ -1,22 +0,0 @@
// 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.
namespace Microsoft.Toolkit.Services.Core
{
/// <summary>
/// PasswordCredential class composed of UserName and Password, both strings.
/// </summary>
public class PasswordCredential
{
/// <summary>
/// Gets or sets the username from login form
/// </summary>
public string UserName { get; set; }
/// <summary>
/// Gets or sets the password from login form
/// </summary>
public string Password { get; set; }
}
}

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

@ -1,43 +0,0 @@
// 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;
namespace Microsoft.Toolkit.Services
{
/// <summary>
/// Exception for null Config.
/// </summary>
public class ConfigNullException : Exception
{
/// <summary>
/// Initializes a new instance of the <see cref="ConfigNullException"/> class.
/// Default constructor.
/// </summary>
public ConfigNullException()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ConfigNullException"/> class.
/// Constructor accepting additional message string.
/// </summary>
/// <param name="message">Additional error information.</param>
public ConfigNullException(string message)
: base(message)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ConfigNullException"/> class.
/// Constructor accepting additional message string and inner exception
/// </summary>
/// <param name="message">Additional error information.</param>
/// <param name="innerException">Reference to inner exception.</param>
public ConfigNullException(string message, Exception innerException)
: base(message, innerException)
{
}
}
}

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

@ -1,43 +0,0 @@
// 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;
namespace Microsoft.Toolkit.Services
{
/// <summary>
/// Exception for config parameter being null.
/// </summary>
public class ConfigParameterNullException : Exception
{
/// <summary>
/// Initializes a new instance of the <see cref="ConfigParameterNullException"/> class.
/// Default constructor.
/// </summary>
public ConfigParameterNullException()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ConfigParameterNullException"/> class.
/// Accepts parameter name.
/// </summary>
/// <param name="parameter">Name of the parameter.</param>
public ConfigParameterNullException(string parameter)
: base(string.Format("The parameter '{0}' in config is null.", parameter))
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ConfigParameterNullException"/> class.
/// Accepts parameter name and inner exception.
/// </summary>
/// <param name="message">Name of the parameter.</param>
/// <param name="innerException">Reference to the inner exception.</param>
public ConfigParameterNullException(string message, Exception innerException)
: base(message, innerException)
{
}
}
}

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

@ -1,43 +0,0 @@
// 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;
namespace Microsoft.Toolkit.Services
{
/// <summary>
/// Exception for no OAuth keys being present.
/// </summary>
public class OAuthKeysNotPresentException : Exception
{
/// <summary>
/// Initializes a new instance of the <see cref="OAuthKeysNotPresentException"/> class.
/// Default constructor.
/// </summary>
public OAuthKeysNotPresentException()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="OAuthKeysNotPresentException"/> class.
/// Constructor with information on missing key.
/// </summary>
/// <param name="key">Name of the missing key.</param>
public OAuthKeysNotPresentException(string key)
: base(string.Format("Open Authentication Key '{0}' not present", key))
{
}
/// <summary>
/// Initializes a new instance of the <see cref="OAuthKeysNotPresentException"/> class.
/// Constructor with additional message and inner exception.
/// </summary>
/// <param name="message">Additional exception message.</param>
/// <param name="innerException">Reference to inner exception.</param>
public OAuthKeysNotPresentException(string message, Exception innerException)
: base(message, innerException)
{
}
}
}

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

@ -1,43 +0,0 @@
// 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;
namespace Microsoft.Toolkit.Services
{
/// <summary>
/// Exception for revoked OAuth keys.
/// </summary>
public class OAuthKeysRevokedException : Exception
{
/// <summary>
/// Initializes a new instance of the <see cref="OAuthKeysRevokedException"/> class.
/// Default constructor.
/// </summary>
public OAuthKeysRevokedException()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="OAuthKeysRevokedException"/> class.
/// Constructor with additional message.
/// </summary>
/// <param name="message">Additional message</param>
public OAuthKeysRevokedException(string message)
: base(message)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="OAuthKeysRevokedException"/> class.
/// Constructor with additional message and inner exception.
/// </summary>
/// <param name="message">Additional message.</param>
/// <param name="innerException">Reference to inner exception.</param>
public OAuthKeysRevokedException(string message, Exception innerException)
: base(message, innerException)
{
}
}
}

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

@ -1,43 +0,0 @@
// 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;
namespace Microsoft.Toolkit.Services
{
/// <summary>
/// Exception for null Parser.
/// </summary>
public class ParserNullException : Exception
{
/// <summary>
/// Initializes a new instance of the <see cref="ParserNullException"/> class.
/// Default constructor.
/// </summary>
public ParserNullException()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ParserNullException"/> class.
/// Constructor with additional message.
/// </summary>
/// <param name="message">Additional message</param>
public ParserNullException(string message)
: base(message)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ParserNullException"/> class.
/// Constructor with additional message and inner exception.
/// </summary>
/// <param name="message">Additional message.</param>
/// <param name="innerException">Reference to inner exception.</param>
public ParserNullException(string message, Exception innerException)
: base(message, innerException)
{
}
}
}

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

@ -1,55 +0,0 @@
// 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;
using System.Net;
namespace Microsoft.Toolkit.Services
{
/// <summary>
/// Exception for failed requests.
/// </summary>
public class RequestFailedException : Exception
{
/// <summary>
/// Initializes a new instance of the <see cref="RequestFailedException"/> class.
/// Default constructor.
/// </summary>
public RequestFailedException()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="RequestFailedException"/> class.
/// Constructor with additional message.
/// </summary>
/// <param name="message">Additional message.</param>
public RequestFailedException(string message)
: base(message)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="RequestFailedException"/> class.
/// Constructor with status code and reason for request failure.
/// </summary>
/// <param name="statusCode">Failure status code.</param>
/// <param name="reason">Failure reason.</param>
public RequestFailedException(HttpStatusCode statusCode, string reason)
: base(string.Format("Request failed with status code {0} and reason '{1}'", (int)statusCode, reason))
{
}
/// <summary>
/// Initializes a new instance of the <see cref="RequestFailedException"/> class.
/// Constructor with additional message and inner exception.
/// </summary>
/// <param name="message">Additional message.</param>
/// <param name="innerException">Reference to inner exception.</param>
public RequestFailedException(string message, Exception innerException)
: base(message, innerException)
{
}
}
}

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

@ -1,43 +0,0 @@
// 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;
namespace Microsoft.Toolkit.Services
{
/// <summary>
/// Exception for too many requests.
/// </summary>
public class TooManyRequestsException : Exception
{
/// <summary>
/// Initializes a new instance of the <see cref="TooManyRequestsException"/> class.
/// Default constructor.
/// </summary>
public TooManyRequestsException()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="TooManyRequestsException"/> class.
/// Constructor with additional message.
/// </summary>
/// <param name="message">Additional message.</param>
public TooManyRequestsException(string message)
: base(message)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="TooManyRequestsException"/> class.
/// Constructor with additional message and reference to inner exception.
/// </summary>
/// <param name="message">Additional message.</param>
/// <param name="innerException">Reference to inner exception.</param>
public TooManyRequestsException(string message, Exception innerException)
: base(message, innerException)
{
}
}
}

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

@ -1,43 +0,0 @@
// 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;
namespace Microsoft.Toolkit.Services
{
/// <summary>
/// Exception for user not found.
/// </summary>
public class UserNotFoundException : Exception
{
/// <summary>
/// Initializes a new instance of the <see cref="UserNotFoundException"/> class.
/// Default constructor.
/// </summary>
public UserNotFoundException()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="UserNotFoundException"/> class.
/// Constructor with screen/user name information.
/// </summary>
/// <param name="screenName">Name of user not found.</param>
public UserNotFoundException(string screenName)
: base("User " + screenName + " not found.")
{
}
/// <summary>
/// Initializes a new instance of the <see cref="UserNotFoundException"/> class.
/// Constructor with screen/user name information and inner exception.
/// </summary>
/// <param name="screenName">Name of user not found.</param>
/// <param name="innerException">Reference to inner exception.</param>
public UserNotFoundException(string screenName, Exception innerException)
: base("User " + screenName + " not found.", innerException)
{
}
}
}

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

@ -1,53 +0,0 @@
<Project Sdk="MSBuild.Sdk.Extras">
<PropertyGroup>
<TargetFrameworks>uap10.0.17763;netstandard2.0;NET462</TargetFrameworks>
<Title>Windows Community Toolkit .NET Standard Services</Title>
<Description>
This .NET standard library enables access to different data sources such as Microsoft Graph, OneDrive, Twitter, Microsoft Translator, and LinkedIn. It is part of the Windows Community Toolkit.
</Description>
<PackageTags>UWP Community Toolkit Windows Microsoft Graph OneDrive Twitter Translator LinkedIn service login OAuth</PackageTags>
<LangVersion>8.0</LangVersion>
<NoWarn>CS8002;CS0618</NoWarn>
<DeterministicSourcePaths Condition="'$(EnableSourceLink)' == ''">false</DeterministicSourcePaths>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'uap10.0.17763'">
<DefineConstants Condition="'$(DisableImplicitFrameworkDefines)' != 'true'">$(DefineConstants);WINRT</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'net462'">
<UseWpf>true</UseWpf>
<EnableDefaultPageItems>false</EnableDefaultPageItems>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Microsoft.Toolkit.Parsers\Microsoft.Toolkit.Parsers.csproj" />
<ProjectReference Include="..\Microsoft.Toolkit\Microsoft.Toolkit.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Text.Json" Version="4.7.2" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)'=='uap10.0.17763'">
<ProjectReference Include="..\Microsoft.Toolkit.Uwp\Microsoft.Toolkit.Uwp.csproj" />
</ItemGroup>
<ItemGroup Condition="!('$(TargetFramework)'=='net462')">
<Compile Remove="PlatformSpecific\NetFramework\**\*" />
<None Remove="PlatformSpecific\NetFramework\**\*" />
<Page Remove="PlatformSpecific\NetFramework\**\*" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)'=='net462'">
<Reference Include="System.Web" />
<PackageReference Include="Microsoft.Toolkit.Wpf.UI.Controls.WebView" Version="[5.0.0-preview.gb86cb1c4cb,)" />
<PackageReference Include="Microsoft.Toolkit.Forms.UI.Controls.WebView" Version="[5.0.0-preview.gb86cb1c4cb,)" />
</ItemGroup>
<ItemGroup Condition="!('$(TargetFramework)'=='uap10.0.17763')">
<Compile Remove="PlatformSpecific\Uwp\**\*" />
</ItemGroup>
</Project>

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

@ -1,78 +0,0 @@
// 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;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
#if WINRT
using Windows.Security.Cryptography;
using Windows.Security.Cryptography.Core;
using Windows.Storage.Streams;
#endif
namespace Microsoft.Toolkit.Services.OAuth
{
/// <summary>
/// OAuth Encoder.
/// </summary>
internal static class OAuthEncoder
{
/// <summary>
/// Url encode input string.
/// </summary>
/// <param name="value">Input string.</param>
/// <returns>Encoded string.</returns>
public static string UrlEncode(string value)
{
if (string.IsNullOrEmpty(value))
{
return string.Empty;
}
var result = Uri.EscapeDataString(value);
// UrlEncode escapes with lowercase characters (e.g. %2f) but oAuth needs %2F
result = Regex.Replace(result, "(%[0-9a-f][0-9a-f])", c => c.Value.ToUpper());
// these characters are not escaped by UrlEncode() but needed to be escaped
result = result
.Replace("(", "%28")
.Replace(")", "%29")
.Replace("$", "%24")
.Replace("!", "%21")
.Replace("*", "%2A")
.Replace("'", "%27");
// these characters are escaped by UrlEncode() but will fail if unescaped!
result = result.Replace("%7E", "~");
return result;
}
/// <summary>
/// Encode list of parameters.
/// </summary>
/// <param name="parameters">List of parameters.</param>
/// <returns>Encoded string of parameters.</returns>
public static string UrlEncode(IEnumerable<OAuthParameter> parameters)
{
string rawUrl = string.Join("&", parameters.OrderBy(p => p.Key).Select(p => p.ToString()).ToArray());
return UrlEncode(rawUrl);
}
#if WINRT
public static string GenerateHash(string input, string key)
{
MacAlgorithmProvider mac = MacAlgorithmProvider.OpenAlgorithm(MacAlgorithmNames.HmacSha1);
IBuffer keyMaterial = CryptographicBuffer.ConvertStringToBinary(key, BinaryStringEncoding.Utf8);
CryptographicKey cryptoKey = mac.CreateKey(keyMaterial);
IBuffer hash = CryptographicEngine.Sign(cryptoKey, CryptographicBuffer.ConvertStringToBinary(input, BinaryStringEncoding.Utf8));
return CryptographicBuffer.EncodeToBase64String(hash);
}
#endif
}
}

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

@ -1,65 +0,0 @@
// 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.Globalization;
namespace Microsoft.Toolkit.Services.OAuth
{
/// <summary>
/// OAuth parameter.
/// </summary>
internal class OAuthParameter
{
/// <summary>
/// Gets or sets key property.
/// </summary>
public string Key { get; set; }
/// <summary>
/// Gets or sets value property.
/// </summary>
public string Value { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="OAuthParameter"/> class.
/// Constructor accepting key and value.
/// </summary>
/// <param name="key">Key.</param>
/// <param name="value">Value.</param>
public OAuthParameter(string key, string value)
{
Key = key;
Value = value;
}
/// <summary>
/// ToString override.
/// </summary>
/// <returns>String representation</returns>
public override string ToString()
{
return ToString(false);
}
/// <summary>
/// Format key / value into string.
/// </summary>
/// <param name="withQuotes">Whether to create quotes in string.</param>
/// <returns>Formatted string of key / value.</returns>
public string ToString(bool withQuotes)
{
string format;
if (withQuotes)
{
format = "{0}=\"{1}\"";
}
else
{
format = "{0}={1}";
}
return string.Format(CultureInfo.InvariantCulture, format, OAuthEncoder.UrlEncode(Key), OAuthEncoder.UrlEncode(Value));
}
}
}

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

@ -1,62 +0,0 @@
// 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;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
namespace Microsoft.Toolkit.Services.OAuth
{
/// <summary>
/// OAuth Uri extensions.
/// </summary>
internal static class OAuthUriExtensions
{
/// <summary>
/// Get query parameters from Uri.
/// </summary>
/// <param name="uri">Uri to process.</param>
/// <returns>Dictionary of query parameters.</returns>
public static IDictionary<string, string> GetQueryParams(this Uri uri)
{
var dict = uri.Query.Remove(0, 1).Split('&').ToDictionary(c => c.Split('=')[0], c => Uri.UnescapeDataString(c.Split('=')[1]));
return dict;
}
/// <summary>
/// Get absolute Uri.
/// </summary>
/// <param name="uri">Uri to process.</param>
/// <returns>Uri without query string.</returns>
public static string AbsoluteWithoutQuery(this Uri uri)
{
if (string.IsNullOrEmpty(uri.Query))
{
return uri.AbsoluteUri;
}
return uri.AbsoluteUri.Replace(uri.Query, string.Empty);
}
/// <summary>
/// Normalize the Uri into string.
/// </summary>
/// <param name="uri">Uri to process.</param>
/// <returns>Normalized string.</returns>
public static string Normalize(this Uri uri)
{
var result = new StringBuilder(string.Format(CultureInfo.InvariantCulture, "{0}://{1}", uri.Scheme, uri.Host));
if (!((uri.Scheme == "http" && uri.Port == 80) || (uri.Scheme == "https" && uri.Port == 443)))
{
result.Append(string.Concat(":", uri.Port));
}
result.Append(uri.AbsolutePath);
return result.ToString();
}
}
}

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

@ -1,81 +0,0 @@
// 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;
using System.Threading.Tasks;
using System.Windows;
using Microsoft.Toolkit.Services.Core;
using ApplicationForm = System.Windows.Forms.Application;
namespace Microsoft.Toolkit.Services.PlatformSpecific.NetFramework
{
internal class NetFrameworkAuthenticationBroker : IAuthenticationBroker
{
public Task<AuthenticationResult> Authenticate(Uri requestUri, Uri callbackUri)
{
int numberForms = ApplicationForm.OpenForms.Count;
if (numberForms > 0)
{
return this.AuthenticateForm(requestUri, callbackUri);
}
else if (Application.Current != null)
{
return this.AuthenticateWindow(requestUri, callbackUri);
}
else
{
// Your code shouldn't reach this exception.
throw new Exception("Cannot identify the current application. Please review your main app");
}
}
public async Task<AuthenticationResult> AuthenticateWindow(Uri requestUri, Uri callbackUri)
{
PopupWPF popupWindow;
var taskCompletionSource = new TaskCompletionSource<AuthenticationResult>();
popupWindow = new PopupWPF(callbackUri);
popupWindow.Closed += (sender, e) =>
{
taskCompletionSource.SetResult(HandleExit(popupWindow.ActualUrl));
};
popupWindow.Show();
popupWindow.NavigateTo(requestUri.AbsoluteUri);
return await taskCompletionSource.Task;
}
public async Task<AuthenticationResult> AuthenticateForm(Uri requestUri, Uri callbackUri)
{
PopupForm popupForm;
var taskCompletionSource = new TaskCompletionSource<AuthenticationResult>();
popupForm = new PopupForm(callbackUri);
popupForm.FormClosed += (sender, e) =>
{
taskCompletionSource.SetResult(HandleExit(popupForm.ActualUrl));
};
popupForm.Show();
popupForm.NavigateTo(requestUri.AbsoluteUri);
return await taskCompletionSource.Task;
}
private AuthenticationResult HandleExit(Uri actualUrl)
{
var result = new AuthenticationResult();
if (actualUrl != null)
{
var query = System.Web.HttpUtility.ParseQueryString(actualUrl.Query);
result.ResponseData = query.ToString();
result.ResponseStatus = AuthenticationResultStatus.Success;
}
else
{
result.ResponseStatus = AuthenticationResultStatus.ErrorHttp;
}
return result;
}
}
}

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

@ -1,70 +0,0 @@
// 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;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.Toolkit.Services.Core;
using static Microsoft.Toolkit.Services.PlatformSpecific.NetFramework.PasswordManagerNativeMethods;
namespace Microsoft.Toolkit.Services.PlatformSpecific.NetFramework
{
internal class NetFrameworkPasswordManager : IPasswordManager
{
public void Store(string resource, PasswordCredential credential)
{
// Validations.
byte[] byteArray = Encoding.Unicode.GetBytes(credential.Password);
// Go ahead with what we have are stuff it into the CredMan structures.
Credential cred = new Credential
{
TargetName = resource,
UserName = credential.UserName,
CredentialBlob = credential.Password,
CredentialBlobSize = (uint)byteArray.Length,
AttributeCount = 0,
Attributes = IntPtr.Zero,
Comment = null,
TargetAlias = null,
Type = CRED_TYPE.GENERIC,
Persist = CRED_PERSIST.LOCAL_MACHINE
};
NativeCredential userCredential = NativeCredential.GetNativeCredential(cred);
// Write the info into the CredMan storage.
bool written = CredWrite(ref userCredential, 0);
int lastError = Marshal.GetLastWin32Error();
if (!written)
{
string message = "CredWrite failed with the error code " + lastError.ToString();
throw new InvalidOperationException(message);
}
}
public PasswordCredential Get(string key)
{
int lastError = Marshal.GetHRForLastWin32Error();
if (!CredRead(key, CRED_TYPE.GENERIC, 0, out var nCredPtr))
{
return null;
}
CriticalCredentialHandle credentialHandle = new CriticalCredentialHandle(nCredPtr);
Credential credential = credentialHandle.GetCredential();
return new PasswordCredential
{
UserName = credential.UserName,
Password = credential.CredentialBlob
};
}
public void Remove(string key)
{
CredDelete(key, CRED_TYPE.GENERIC, 0);
}
}
}

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

@ -1,40 +0,0 @@
// 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;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Toolkit.Services.Core;
namespace Microsoft.Toolkit.Services.PlatformSpecific.NetFramework
{
internal class NetFrameworkSignatureManager : ISignatureManager
{
/// <summary>
/// Generate request signature.
/// </summary>
/// <param name="baseString">String to sign</param>
/// <param name="secret">Secret to use to sign</param>
/// <param name="append">If true append &amp; to the base string</param>
/// <returns>Signature.</returns>
public string GetSignature(string baseString, string secret, bool append = false)
{
var key = append ? secret + "&" : secret;
var baseStringByte = Encoding.UTF8.GetBytes(baseString);
var keyByte = Encoding.UTF8.GetBytes(key);
using (HMACSHA1 hmac = new HMACSHA1(keyByte))
{
hmac.Initialize();
var hash = hmac.ComputeHash(baseStringByte);
string base64 = Convert.ToBase64String(hash);
return base64;
}
}
}
}

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

@ -1,57 +0,0 @@
// 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;
using System.Collections.Generic;
using System.IO;
using System.IO.IsolatedStorage;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Toolkit.Services.Core;
namespace Microsoft.Toolkit.Services.PlatformSpecific.NetFramework
{
internal class NetFrameworkStorageManager : IStorageManager
{
private const string FileName = "credential_service_data.txt";
private const char Separator = ':';
public async Task<string> GetAsync(string key)
{
var isoStore = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly, null, null);
using (IsolatedStorageFileStream isoStream = new IsolatedStorageFileStream(FileName, FileMode.OpenOrCreate, isoStore))
{
using (StreamReader reader = new StreamReader(isoStream))
{
while (!reader.EndOfStream)
{
var line = (await reader.ReadLineAsync()).Split(Separator);
var currentKey = line.First();
if (currentKey == key)
{
return line.Last();
}
}
}
}
return null;
}
public Task SetAsync(string key, string value)
{
var isoStore = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly, null, null);
using (IsolatedStorageFileStream isoStream = new IsolatedStorageFileStream(FileName, FileMode.Append, isoStore))
{
using (StreamWriter writer = new StreamWriter(isoStream))
{
return writer.WriteLineAsync(string.Concat(key, Separator, value));
}
}
}
}
}

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

@ -1,161 +0,0 @@
// 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;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
namespace Microsoft.Toolkit.Services.PlatformSpecific.NetFramework
{
internal class PasswordManagerNativeMethods
{
[DllImport("Advapi32.dll", EntryPoint = "CredReadW", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern bool CredRead(string target, CRED_TYPE type, int reservedFlag, out IntPtr credentialPtr);
[DllImport("Advapi32.dll", EntryPoint = "CredWriteW", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern bool CredWrite([In] ref NativeCredential userCredential, [In] uint flags);
[DllImport("Advapi32.dll", EntryPoint = "CredFree", SetLastError = true)]
internal static extern bool CredFree([In] IntPtr cred);
[DllImport("advapi32.dll", EntryPoint = "CredDeleteW", CharSet = CharSet.Unicode)]
internal static extern bool CredDelete(string target, CRED_TYPE type, int flags);
internal enum CRED_TYPE : uint
{
GENERIC = 1,
DOMAIN_PASSWORD = 2,
DOMAIN_CERTIFICATE = 3,
DOMAIN_VISIBLE_PASSWORD = 4,
GENERIC_CERTIFICATE = 5,
DOMAIN_EXTENDED = 6,
MAXIMUM = 7, // Maximum supported cred type
MAXIMUM_EX = MAXIMUM + 1000, // Allow new applications to run on old OSes
}
internal enum CRED_PERSIST : uint
{
SESSION = 1,
LOCAL_MACHINE = 2,
ENTERPRISE = 3,
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct NativeCredential
{
internal uint Flags;
internal CRED_TYPE Type;
internal IntPtr TargetName;
internal IntPtr Comment;
internal System.Runtime.InteropServices.ComTypes.FILETIME LastWritten;
internal uint CredentialBlobSize;
internal IntPtr CredentialBlob;
internal uint Persist;
internal uint AttributeCount;
internal IntPtr Attributes;
internal IntPtr TargetAlias;
internal IntPtr UserName;
/// <summary>
/// This method derives a NativeCredential instance from a given Credential instance.
/// </summary>
/// <param name="cred">The managed Credential counterpart containing data to be stored.</param>
/// <returns>A NativeCredential instance that is derived from the given Credential
/// instance.</returns>
internal static NativeCredential GetNativeCredential(Credential cred)
{
return new NativeCredential
{
AttributeCount = 0,
Attributes = IntPtr.Zero,
Comment = IntPtr.Zero,
TargetAlias = IntPtr.Zero,
Type = CRED_TYPE.GENERIC,
Persist = (uint)cred.Persist,
CredentialBlobSize = (uint)cred.CredentialBlobSize,
TargetName = Marshal.StringToCoTaskMemUni(cred.TargetName),
CredentialBlob = Marshal.StringToCoTaskMemUni(cred.CredentialBlob),
UserName = Marshal.StringToCoTaskMemUni(cred.UserName)
};
}
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct Credential
{
internal uint Flags;
internal CRED_TYPE Type;
internal string TargetName;
internal string Comment;
internal System.Runtime.InteropServices.ComTypes.FILETIME LastWritten;
internal uint CredentialBlobSize;
internal string CredentialBlob;
internal CRED_PERSIST Persist;
internal uint AttributeCount;
internal IntPtr Attributes;
internal string TargetAlias;
internal string UserName;
}
/// <summary>
/// Handle and create the credential.
/// </summary>
internal sealed class CriticalCredentialHandle : CriticalHandleZeroOrMinusOneIsInvalid
{
// Set the handle.
internal CriticalCredentialHandle(IntPtr preexistingHandle)
{
SetHandle(preexistingHandle);
}
internal Credential GetCredential()
{
if (!IsInvalid)
{
// Get the Credential from the mem location
NativeCredential nativeCredential = (NativeCredential)Marshal.PtrToStructure(handle, typeof(NativeCredential));
// Create a managed Credential type and fill it with data from the native counterpart.
return new Credential
{
CredentialBlobSize = nativeCredential.CredentialBlobSize,
CredentialBlob = Marshal.PtrToStringUni(nativeCredential.CredentialBlob, (int)nativeCredential.CredentialBlobSize / 2),
UserName = Marshal.PtrToStringUni(nativeCredential.UserName),
TargetName = Marshal.PtrToStringUni(nativeCredential.TargetName),
TargetAlias = Marshal.PtrToStringUni(nativeCredential.TargetAlias),
Type = nativeCredential.Type,
Flags = nativeCredential.Flags,
Persist = (CRED_PERSIST)nativeCredential.Persist
};
}
else
{
throw new InvalidOperationException("Invalid CriticalHandle!");
}
}
// Perform any specific actions to release the handle in the ReleaseHandle method.
// Often, you need to use PInvoke to make a call into the Win32 API to release the
// handle. In this case, however, we can use the Marshal class to release the unmanaged memory.
protected override bool ReleaseHandle()
{
// If the handle was set, free it. Return success.
if (!IsInvalid)
{
// NOTE: We should also ZERO out the memory allocated to the handle, before freeing it
// so there are no traces of the sensitive data left in memory.
CredFree(handle);
// Mark the handle as invalid for future users.
SetHandleAsInvalid();
return true;
}
// Return false.
return false;
}
}
}
}

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

@ -1,67 +0,0 @@
// 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.
namespace Microsoft.Toolkit.Services.PlatformSpecific.NetFramework
{
partial class PopupForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.webView1 = new Microsoft.Toolkit.Forms.UI.Controls.WebView();
((System.ComponentModel.ISupportInitialize)(this.webView1)).BeginInit();
this.SuspendLayout();
//
// webView1
//
this.webView1.Dock = System.Windows.Forms.DockStyle.Fill;
this.webView1.Location = new System.Drawing.Point(0, 0);
this.webView1.MinimumSize = new System.Drawing.Size(20, 20);
this.webView1.Name = "webView1";
this.webView1.Size = new System.Drawing.Size(800, 450);
this.webView1.TabIndex = 0;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.webView1);
this.Name = "Form1";
this.Text = "Form1";
((System.ComponentModel.ISupportInitialize)(this.webView1)).EndInit();
this.ResumeLayout(false);
}
#endregion
private Microsoft.Toolkit.Forms.UI.Controls.WebView webView1;
}
}

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

@ -1,77 +0,0 @@
// 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;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Microsoft.Toolkit.Services.PlatformSpecific.NetFramework
{
/// <summary>
/// Service WebView for windows forms
/// </summary>
public partial class PopupForm : Form
{
private string initialHost;
private string callbackHost;
/// <summary>
/// Gets or sets the current URL before closing the form
/// </summary>
public Uri ActualUrl { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="PopupForm"/> class.
/// </summary>
/// <param name="callbackUrl">Uri callback url</param>
public PopupForm(Uri callbackUrl)
{
InitializeComponent();
webView1.NavigationStarting += (s, e) => WebViewNavigationStartingHandler(e.Uri);
callbackHost = GetTopLevelDomain(callbackUrl);
}
private void WebViewNavigationStartingHandler(Uri uri)
{
var topLevelDomain = GetTopLevelDomain(uri);
if (initialHost != topLevelDomain && topLevelDomain == callbackHost)
{
ActualUrl = uri;
this.Close();
}
}
/// <summary>
/// Loads a given url in the WebView
/// </summary>
/// <param name="url">Url string to navigate to.</param>
public void NavigateTo(string url)
{
initialHost = GetTopLevelDomain(url);
webView1.Navigate(url);
}
private string GetTopLevelDomain(string url)
{
return GetTopLevelDomain(new Uri(url));
}
private string GetTopLevelDomain(Uri url)
{
var hostParts = url.Host.Split('.').Select(x => x.ToString());
if (hostParts.Count() > 1)
{
return hostParts.ElementAt(1);
}
return hostParts.ElementAt(0);
}
}
}

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

@ -1,13 +0,0 @@
<Window x:Class="Microsoft.Toolkit.Services.PlatformSpecific.NetFramework.PopupWPF"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Microsoft.Toolkit.Services.PlatformSpecific.NetFramework"
xmlns:Controls="clr-namespace:Microsoft.Toolkit.Wpf.UI.Controls;assembly=Microsoft.Toolkit.Wpf.UI.Controls.WebView"
mc:Ignorable="d"
Title="PopupPage" Height="450" Width="800">
<Grid>
<Controls:WebView Grid.Row="0" x:Name="WebView1" Width="800" Height="800" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top"/>
</Grid>
</Window>

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

@ -1,83 +0,0 @@
// 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;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace Microsoft.Toolkit.Services.PlatformSpecific.NetFramework
{
/// <summary>
/// Interaction logic for PopupWPF.xaml
/// </summary>
public partial class PopupWPF : Window
{
private string initialHost;
private string callbackHost;
/// <summary>
/// Gets or sets the current URL before closing the form
/// </summary>
public Uri ActualUrl { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="PopupWPF"/> class.
/// </summary>
/// <param name="callbackUrl">Uri callback url</param>
public PopupWPF(Uri callbackUrl)
{
InitializeComponent();
WebView1.NavigationStarting += (s, e) => WebViewNavigationStartingHandler(e.Uri);
callbackHost = GetTopLevelDomain(callbackUrl);
}
private void WebViewNavigationStartingHandler(Uri uri)
{
var topLevelDomain = GetTopLevelDomain(uri);
if (initialHost != topLevelDomain && topLevelDomain == callbackHost)
{
ActualUrl = uri;
this.Close();
}
}
/// <summary>
/// Loads a given url in the WebView
/// </summary>
/// <param name="url">Url string to navigate to.</param>
public void NavigateTo(string url)
{
initialHost = GetTopLevelDomain(url);
WebView1.Navigate(url);
}
private string GetTopLevelDomain(string url)
{
return GetTopLevelDomain(new Uri(url));
}
private string GetTopLevelDomain(Uri url)
{
var hostParts = url.Host.Split('.').Select(x => x.ToString());
if (hostParts.Count() > 1)
{
return hostParts.ElementAt(1);
}
return hostParts.ElementAt(0);
}
}
}

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

@ -1,44 +0,0 @@
// 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;
using System.Threading.Tasks;
using Microsoft.Toolkit.Services.Core;
using Windows.Security.Authentication.Web;
namespace Microsoft.Toolkit.Services.PlatformSpecific.Uwp
{
/// <summary>
/// Authentication Broker
/// </summary>
internal class UwpAuthenticationBroker : IAuthenticationBroker
{
/// <summary>
/// Authentication process
/// </summary>
/// <param name="requestUri"> Request Uri</param>
/// <param name="callbackUri"> Uri result</param>
/// <returns> Returns login status</returns>
public async Task<AuthenticationResult> Authenticate(Uri requestUri, Uri callbackUri)
{
WebAuthenticationResult result = await WebAuthenticationBroker.AuthenticateAsync(
WebAuthenticationOptions.None,
requestUri,
callbackUri);
switch (result.ResponseStatus)
{
case WebAuthenticationStatus.Success:
return new AuthenticationResult { ResponseData = result.ResponseData, ResponseStatus = AuthenticationResultStatus.Success };
case WebAuthenticationStatus.UserCancel:
return new AuthenticationResult { ResponseData = result.ResponseData, ResponseStatus = AuthenticationResultStatus.UserCancel, ResponseErrorDetail = result.ResponseErrorDetail };
case WebAuthenticationStatus.ErrorHttp:
return new AuthenticationResult { ResponseData = result.ResponseData, ResponseStatus = AuthenticationResultStatus.ErrorHttp, ResponseErrorDetail = result.ResponseErrorDetail };
default:
// TODO: Change with correct name;
throw new ArgumentException("error");
}
}
}
}

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

@ -1,67 +0,0 @@
// 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.Linq;
using Microsoft.Toolkit.Services.Core;
using Windows.Security.Credentials;
namespace Microsoft.Toolkit.Services.PlatformSpecific.Uwp
{
/// <summary>
/// Password Manager
/// </summary>
internal class UwpPasswordManager : IPasswordManager
{
/// <summary>
/// Password vault used to store access tokens
/// </summary>
private readonly PasswordVault _vault;
/// <summary>
/// Initializes a new instance of the <see cref="UwpPasswordManager"/> class.
/// </summary>
public UwpPasswordManager()
{
_vault = new PasswordVault();
}
/// <inheritdoc/>
public Toolkit.Services.Core.PasswordCredential Get(string key)
{
var credentials = RetrievePasswordCredential(key);
if (credentials == null)
{
return null;
}
return new Toolkit.Services.Core.PasswordCredential { Password = credentials.Password, UserName = credentials.UserName };
}
private Windows.Security.Credentials.PasswordCredential RetrievePasswordCredential(string key)
{
var passwordCredentials = _vault.RetrieveAll();
var temp = passwordCredentials.FirstOrDefault(c => c.Resource == key);
if (temp == null)
{
return null;
}
return _vault.Retrieve(temp.Resource, temp.UserName);
}
/// <inheritdoc/>
public void Remove(string key)
{
_vault.Remove(RetrievePasswordCredential(key));
}
/// <inheritdoc/>
public void Store(string resource, Toolkit.Services.Core.PasswordCredential credentials)
{
var passwordCredential = new Windows.Security.Credentials.PasswordCredential(resource, credentials.UserName, credentials.Password);
_vault.Add(passwordCredential);
}
}
}

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

@ -1,37 +0,0 @@
// 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.Toolkit.Services.Core;
using Windows.Security.Cryptography;
using Windows.Security.Cryptography.Core;
using Windows.Storage.Streams;
namespace Microsoft.Toolkit.Services.PlatformSpecific.Uwp
{
/// <summary>
/// UWP specific signature generator using cryptographic library
/// </summary>
internal class UwpSignatureManager : ISignatureManager
{
/// <summary>
/// Generate request signature.
/// </summary>
/// <param name="baseString">String to sign</param>
/// <param name="secret">Secret to use to sign</param>
/// <param name="append">If true append &amp; to the base string</param>
/// <returns>Signature.</returns>
public string GetSignature(string baseString, string secret, bool append = false)
{
var key = append ? secret + "&" : secret;
IBuffer keyMaterial = CryptographicBuffer.ConvertStringToBinary(key, BinaryStringEncoding.Utf8);
MacAlgorithmProvider mac = MacAlgorithmProvider.OpenAlgorithm(MacAlgorithmNames.HmacSha1);
CryptographicKey cryptoKey = mac.CreateKey(keyMaterial);
IBuffer dataToBeSigned = CryptographicBuffer.ConvertStringToBinary(baseString, BinaryStringEncoding.Utf8);
IBuffer hash = CryptographicEngine.Sign(cryptoKey, dataToBeSigned);
return CryptographicBuffer.EncodeToBase64String(hash);
}
}
}

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

@ -1,40 +0,0 @@
// 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.Linq;
using System.Threading.Tasks;
using Microsoft.Toolkit.Services.Core;
using Windows.Security.Credentials;
using Windows.Storage;
namespace Microsoft.Toolkit.Services.PlatformSpecific.Uwp
{
/// <summary>
/// UWP specific implementation for IStorageManager using ApplicationData and LocalSettings
/// </summary>
internal class UwpStorageManager : IStorageManager
{
/// <summary>
/// Read the storage to return the key if exists if not null;
/// </summary>
/// <param name="key">Key to lookup</param>
/// <returns>Return string value if exists if not null</returns>
public Task<string> GetAsync(string key)
{
return Task.FromResult<string>(ApplicationData.Current.LocalSettings.Values[key]?.ToString());
}
/// <summary>
/// Save the value in the key inside the storage
/// </summary>
/// <param name="key">Key name in storage</param>
/// <param name="value">Value associated to the storage</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public Task SetAsync(string key, string value)
{
ApplicationData.Current.LocalSettings.Values[key] = value;
return Task.CompletedTask;
}
}
}

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

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Library Name="Microsoft.Toolkit.Services">
<Namespace Name="System.Text.Json.Serialization.Converters" Dynamic="Required All"/>
</Library>
</Directives>

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

@ -1,22 +0,0 @@
// 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.
namespace Microsoft.Toolkit.Services.LinkedIn
{
/// <summary>
/// Constant strings for LinkedIn Service.
/// </summary>
public static class LinkedInConstants
{
/// <summary>
/// Storage key name for access token.
/// </summary>
public static readonly string STORAGEKEYACCESSTOKEN = "LinkedInAccessToken";
/// <summary>
/// Storage key name for user name.
/// </summary>
public static readonly string STORAGEKEYUSER = "LinkedInUser";
}
}

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

@ -1,32 +0,0 @@
// 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.
namespace Microsoft.Toolkit.Services.LinkedIn
{
/// <summary>
/// Strong type representation of Content.
/// </summary>
public class LinkedInContent
{
/// <summary>
/// Gets or sets title property.
/// </summary>
public string Title { get; set; }
/// <summary>
/// Gets or sets description property.
/// </summary>
public string Description { get; set; }
/// <summary>
/// Gets or sets submitted url property.
/// </summary>
public string SubmittedUrl { get; set; }
/// <summary>
/// Gets or sets submitted image url property.
/// </summary>
public string SubmittedImageUrl { get; set; }
}
}

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

@ -1,17 +0,0 @@
// 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.
namespace Microsoft.Toolkit.Services.LinkedIn
{
/// <summary>
/// Configuration object for specifying richer query information.
/// </summary>
public class LinkedInDataConfig
{
/// <summary>
/// Gets or sets the query string for filtering service results.
/// </summary>
public string Query { get; set; }
}
}

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

@ -1,334 +0,0 @@
// 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;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.Toolkit.Services.Core;
#if WINRT
using Microsoft.Toolkit.Services.PlatformSpecific.Uwp;
#endif
#if NET462
using Microsoft.Toolkit.Services.PlatformSpecific.NetFramework;
#endif
namespace Microsoft.Toolkit.Services.LinkedIn
{
/// <summary>
/// Data Provider for connecting to LinkedIn service.
/// </summary>
public class LinkedInDataProvider
{
private const string _oAuthBaseUrl = "https://www.linkedin.com/uas/oauth2/";
private const string _baseUrl = "https://api.linkedin.com/v1";
private static HttpClient client = new HttpClient();
/// <summary>
/// Gets or sets logged in user information.
/// </summary>
public string Username { get; set; }
/// <summary>
/// Gets a value indicating whether the provider is already logged in
/// </summary>
public bool LoggedIn { get; private set; }
/// <summary>
/// Gets or sets requiredPermissions property.
/// </summary>
public LinkedInPermissions RequiredPermissions { get; set; }
private readonly IAuthenticationBroker _authentication;
private readonly IPasswordManager _passwordManager;
private readonly IStorageManager _storageManager;
/// <summary>
/// Gets or sets tokens property.
/// </summary>
public LinkedInOAuthTokens Tokens { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="LinkedInDataProvider"/> class.
/// Constructor.
/// </summary>
/// <param name="tokens">OAuth tokens for request.</param>
/// <param name="requiredPermissions">Required permissions for the session.</param>
/// <param name="authentication">Authentication result interface.</param>
/// <param name="passwordManager">Password Manager interface, store the password.</param>
/// <param name="storageManager">Storage Manager interface.</param>
public LinkedInDataProvider(LinkedInOAuthTokens tokens, LinkedInPermissions requiredPermissions, IAuthenticationBroker authentication, IPasswordManager passwordManager, IStorageManager storageManager)
{
if (string.IsNullOrEmpty(tokens.ClientSecret))
{
throw new ArgumentException("Missing client secret key");
}
if (string.IsNullOrEmpty(tokens.ClientId))
{
throw new ArgumentException("Missing client ID");
}
if (string.IsNullOrEmpty(tokens.CallbackUri))
{
throw new ArgumentException("Missing callback uri");
}
// Check if its a valid combination of LinkedInPermissions
if ((~(int)LinkedInPermissionsHelpers.AllPermissions & (int)requiredPermissions) != 0)
{
throw new ArgumentException("Error retrieving required permissions");
}
Tokens = tokens;
RequiredPermissions = requiredPermissions;
_authentication = authentication ?? throw new ArgumentException("Invalid AuthenticationBroker");
_storageManager = storageManager ?? throw new ArgumentException("Invalid StorageManager");
_passwordManager = passwordManager ?? throw new ArgumentException("Invalid PasswordManager");
}
#if WINRT
/// <summary>
/// Initializes a new instance of the <see cref="LinkedInDataProvider"/> class.
/// Constructor.
/// </summary>
/// <param name="tokens">OAuth tokens for request.</param>
/// <param name="requiredPermissions">Required permissions for the session.</param>
public LinkedInDataProvider(LinkedInOAuthTokens tokens, LinkedInPermissions requiredPermissions)
: this(tokens, requiredPermissions, new UwpAuthenticationBroker(), new UwpPasswordManager(), new UwpStorageManager())
{
}
#endif
#if NET462
/// <summary>
/// Initializes a new instance of the <see cref="LinkedInDataProvider"/> class.
/// Constructor.
/// </summary>
/// <param name="tokens">OAuth tokens for request.</param>
/// <param name="requiredPermissions">Required permissions for the session.</param>
public LinkedInDataProvider(LinkedInOAuthTokens tokens, LinkedInPermissions requiredPermissions)
: this(tokens, requiredPermissions, new NetFrameworkAuthenticationBroker(), new NetFrameworkPasswordManager(), new NetFrameworkStorageManager())
{
}
#endif
/// <summary>
/// Log user in to LinkedIn.
/// </summary>
/// <returns>Boolean indicating login success.</returns>
public async Task<bool> LoginAsync()
{
var user = await _storageManager.GetAsync(LinkedInConstants.STORAGEKEYUSER);
var credential = _passwordManager.Get(LinkedInConstants.STORAGEKEYACCESSTOKEN);
if (!string.IsNullOrEmpty(user) && credential != null)
{
Tokens.AccessToken = credential.Password;
Username = user;
LoggedIn = true;
return true;
}
string authorizeCode = await GetAuthorizeCodeAsync(Tokens, RequiredPermissions);
if (!string.IsNullOrEmpty(authorizeCode))
{
var accessToken = await GetAccessTokenAsync(Tokens, authorizeCode);
if (!string.IsNullOrEmpty(accessToken))
{
Tokens.AccessToken = accessToken;
_passwordManager.Store(LinkedInConstants.STORAGEKEYACCESSTOKEN, new PasswordCredential { UserName = LinkedInConstants.STORAGEKEYUSER, Password = accessToken });
await _storageManager.SetAsync(LinkedInConstants.STORAGEKEYUSER, LinkedInConstants.STORAGEKEYUSER);
return true;
}
}
LoggedIn = false;
return false;
}
/// <summary>
/// Log user out of LinkedIn.
/// </summary>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public async Task LogoutAsync()
{
var credential = _passwordManager.Get(LinkedInConstants.STORAGEKEYACCESSTOKEN);
if (credential != null)
{
_passwordManager.Remove(LinkedInConstants.STORAGEKEYACCESSTOKEN);
await _storageManager.SetAsync(LinkedInConstants.STORAGEKEYUSER, null);
}
LoggedIn = false;
}
/// <summary>
/// Wrapper around REST API for making data request.
/// </summary>
/// <typeparam name="TSchema">Schema to use</typeparam>
/// <param name="config">Query configuration.</param>
/// <param name="maxRecords">Upper limit for records returned.</param>
/// <param name="startRecord">Index of paged results.</param>
/// <param name="fields">A comma separated string of required fields, which will have strongly typed representation in the model passed in.</param>
/// <returns>Strongly typed list of results.</returns>
public async Task<IEnumerable<TSchema>> GetDataAsync<TSchema>(LinkedInDataConfig config, int maxRecords, int startRecord = 0, string fields = "id")
{
var parser = new LinkedInParser<TSchema>();
var url = $"{_baseUrl}{config.Query}/~:({fields})?oauth2_access_token={Tokens.AccessToken}&format=json&count={maxRecords}&start={startRecord}";
using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, new Uri(url));
request.Headers.Connection.TryParseAdd("Keep-Alive");
using var response = await client.SendAsync(request).ConfigureAwait(false);
var data = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
if (response.IsSuccessStatusCode && !string.IsNullOrEmpty(data))
{
return parser.Parse(data);
}
throw new RequestFailedException((System.Net.HttpStatusCode)response.StatusCode, data);
}
/// <summary>
/// Share data to LinkedIn.
/// </summary>
/// <typeparam name="T">Schema of data to share.</typeparam>
/// <typeparam name="U">Type of response object.</typeparam>
/// <param name="dataToShare">Share request content.</param>
/// <returns>Boolean indicating success or failure.</returns>
public async Task<U> ShareDataAsync<T, U>(T dataToShare)
{
var shareRequest = dataToShare as LinkedInShareRequest;
if (shareRequest != null)
{
LinkedInVisibility.ParseVisibilityStringToEnum(shareRequest.Visibility.Code);
var requestParser = new LinkedInParser<LinkedInShareRequest>();
var url = $"{_baseUrl}/people/~/shares?oauth2_access_token={Tokens.AccessToken}&format=json";
using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, new Uri(url));
request.Headers.Add("x-li-format", "json");
var stringContent = requestParser.Parse(shareRequest);
request.Content = new StringContent(stringContent, Encoding.UTF8, "application/json");
using var response = await client.SendAsync(request).ConfigureAwait(false);
var data = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
var responseParser = new LinkedInParser<U>();
var listResults = responseParser.Parse(data) as List<U>;
return listResults[0];
}
return default(U);
}
/// <summary>
/// Check validity of configuration.
/// </summary>
/// <param name="config">Query configuration.</param>
protected void ValidateConfig(LinkedInDataConfig config)
{
if (config?.Query == null)
{
throw new ConfigParameterNullException(nameof(config.Query));
}
}
private async Task<string> GetAccessTokenAsync(LinkedInOAuthTokens tokens, string authorizeCode)
{
var url = $"{_oAuthBaseUrl}accessToken?grant_type=authorization_code"
+ "&code=" + authorizeCode
+ "&redirect_uri=" + Uri.EscapeDataString(tokens.CallbackUri)
+ "&client_id=" + tokens.ClientId
+ "&client_secret=" + tokens.ClientSecret;
using var request = new HttpRequestMessage(HttpMethod.Post, new Uri(url));
using var response = await client.SendAsync(request).ConfigureAwait(false);
using var jsonStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
using var jsonDoc = await JsonDocument.ParseAsync(jsonStream).ConfigureAwait(false);
var value = jsonDoc.RootElement.GetProperty("access_token");
return value.GetString();
}
private async Task<string> GetAuthorizeCodeAsync(LinkedInOAuthTokens tokens, LinkedInPermissions permissions)
{
string scopes = ConvertPermissionsToEncodedScopeString(permissions);
var url = $"{_oAuthBaseUrl}authorization?response_type=code"
+ "&client_id=" + tokens.ClientId
+ "&state=STATE"
+ "&redirect_uri=" + Uri.EscapeDataString(tokens.CallbackUri)
+ "&" + scopes;
var startUri = new Uri(url);
var endUri = new Uri(tokens.CallbackUri);
var result = await _authentication.Authenticate(startUri, endUri);
switch (result.ResponseStatus)
{
case AuthenticationResultStatus.Success:
{
var response = result.ResponseData;
IDictionary<string, string> dictionary = new Dictionary<string, string>();
var split = response.Split('?');
foreach (var keyValue in split[split.Length - 1].Split('&'))
{
var keyValueSplit = keyValue.Split('=');
if (keyValueSplit.Length == 2)
{
dictionary.Add(keyValueSplit[0], keyValueSplit[1]);
}
}
return dictionary["code"];
}
case AuthenticationResultStatus.ErrorHttp:
Debug.WriteLine("WAB failed, message={0}", result.ResponseErrorDetail.ToString());
return string.Empty;
case AuthenticationResultStatus.UserCancel:
Debug.WriteLine("WAB user aborted.");
return string.Empty;
}
return string.Empty;
}
private string ConvertPermissionsToEncodedScopeString(LinkedInPermissions requiredPermissions)
{
StringBuilder scope = new StringBuilder();
foreach (LinkedInPermissions value in Enum.GetValues(typeof(LinkedInPermissions)))
{
if ((requiredPermissions & value) != LinkedInPermissions.NotSet)
{
var name = value.ToString().ToLower();
name = name.Replace("readwrite", "rw_");
name = name.Replace("read", "r_");
name = name.Replace("write", "w_");
name = name.Replace("companyadmin", "company_admin");
scope.Append($"{name} ");
}
}
return "scope=" + Uri.EscapeDataString(scope.ToString());
}
}
}

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

@ -1,37 +0,0 @@
// 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.
namespace Microsoft.Toolkit.Services.LinkedIn
{
/// <summary>
/// LinkedIn OAuth tokens.
/// </summary>
public class LinkedInOAuthTokens
{
/// <summary>
/// Gets or sets clientId.
/// </summary>
public string ClientId { get; set; }
/// <summary>
/// Gets or sets clientSecret.
/// </summary>
public string ClientSecret { get; set; }
/// <summary>
/// Gets or sets callback Uri.
/// </summary>
public string CallbackUri { get; set; }
/// <summary>
/// Gets or sets access token.
/// </summary>
public string AccessToken { get; set; }
/// <summary>
/// Gets or sets access token Secret.
/// </summary>
public string AccessTokenSecret { get; set; }
}
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше