Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Add Span<T> Base64 conversion APIs that support UTF-8 #24888

Merged
merged 7 commits into from
Oct 27, 2017
Merged
21 changes: 21 additions & 0 deletions src/System.Memory/ref/System.Memory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,14 @@ public abstract class OwnedMemory<T> : IDisposable, IRetainable
public abstract void Retain();
protected internal abstract bool TryGetArray(out ArraySegment<T> arraySegment);
}

public enum OperationStatus
{
Done,
DestinationTooSmall,
NeedMoreData,
InvalidData,
}
}

namespace System.Buffers.Binary
Expand Down Expand Up @@ -277,4 +285,17 @@ public static class BinaryPrimitives
public static bool TryWriteUInt32BigEndian(Span<byte> buffer, uint value) { throw null; }
public static bool TryWriteUInt64BigEndian(Span<byte> buffer, ulong value) { throw null; }
}
}

namespace System.Buffers.Text
{
public static class Base64
{
public static OperationStatus EncodeToUtf8(ReadOnlySpan<byte> bytes, Span<byte> utf8, out int consumed, out int written, bool isFinalBlock = true) { throw null; }
public static OperationStatus EncodeToUtf8InPlace(Span<byte> buffer, int dataLength, out int written) { throw null; }
public static int GetMaxEncodedToUtf8Length(int length) { throw null; }
public static OperationStatus DecodeFromUtf8(ReadOnlySpan<byte> utf8, Span<byte> bytes, out int consumed, out int written, bool isFinalBlock = true) { throw null; }
public static OperationStatus DecodeFromUtf8InPlace(Span<byte> buffer, out int written) { throw null; }
public static int GetMaxDecodedFromUtf8Length(int length) { throw null; }
}
}
5 changes: 4 additions & 1 deletion src/System.Memory/src/System.Memory.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,16 @@
<Compile Include="System\SpanExtensions.cs" />
<Compile Include="System\SpanHelpers.T.cs" />
<Compile Include="System\SpanHelpers.byte.cs" />
<Compile Include="System\ThrowHelper.cs" />
<Compile Include="System\Buffers\OperationStatus.cs" />
<Compile Include="System\Buffers\Binary\Reader.cs" />
<Compile Include="System\Buffers\Binary\ReaderBigEndian.cs" />
<Compile Include="System\Buffers\Binary\ReaderLittleEndian.cs" />
<Compile Include="System\Buffers\Binary\Writer.cs" />
<Compile Include="System\Buffers\Binary\WriterBigEndian.cs" />
<Compile Include="System\Buffers\Binary\WriterLittleEndian.cs" />
<Compile Include="System\Buffers\Text\Base64Decoder.cs" />
<Compile Include="System\Buffers\Text\Base64Encoder.cs" />
</ItemGroup>
<ItemGroup Condition="'$(IsPartialFacadeAssembly)' != 'true'">
<Compile Include="System\ReadOnlySpan.cs" />
Expand All @@ -39,7 +43,6 @@
<Compile Include="System\SpanExtensions.Portable.cs" />
<Compile Include="System\SpanHelpers.cs" />
<Compile Include="System\Pinnable.cs" />
<Compile Include="System\ThrowHelper.cs" />
<Compile Include="System\SpanHelpers.Clear.cs" />
<Compile Include="System\Memory.cs" />
<Compile Include="System\MemoryDebugView.cs" />
Expand Down
6 changes: 3 additions & 3 deletions src/System.Memory/src/System/Buffers/Binary/Reader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,12 @@ public static T ReadMachineEndian<T>(ReadOnlySpan<byte> buffer)
#else
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
{
throw new ArgumentException(SR.Format(SR.Argument_InvalidTypeWithPointersNotSupported, typeof(T)));
ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the reason for this change?

Copy link
Member Author

@ahsonkhan ahsonkhan Oct 26, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From @KrzysztofCwalina

If you do decide to throw, throw from a helper to allow inlining.

Previously, ThrowHelper.cs was not included for netcoreapp, but I updated the project file to always include ThrowHelper.cs. It is the same exception and message.

Copy link
Member

@jkotas jkotas Oct 26, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes in this file should have zero effect on the inlining or the native code that will be generated. I do not see a problem with, but I do not think they help or hurt anything.

}
#endif
if (Unsafe.SizeOf<T>() > buffer.Length)
{
throw new ArgumentOutOfRangeException();
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.length);
}
return Unsafe.ReadUnaligned<T>(ref buffer.DangerousGetPinnableReference());
}
Expand All @@ -132,7 +132,7 @@ public static bool TryReadMachineEndian<T>(ReadOnlySpan<byte> buffer, out T valu
#else
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
{
throw new ArgumentException(SR.Format(SR.Argument_InvalidTypeWithPointersNotSupported, typeof(T)));
ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T));
}
#endif
if (Unsafe.SizeOf<T>() > (uint)buffer.Length)
Expand Down
6 changes: 3 additions & 3 deletions src/System.Memory/src/System/Buffers/Binary/Writer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ public static void WriteMachineEndian<T>(Span<byte> buffer, ref T value)
#else
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
{
throw new ArgumentException(SR.Format(SR.Argument_InvalidTypeWithPointersNotSupported, typeof(T)));
ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T));
}
#endif
if ((uint)Unsafe.SizeOf<T>() > (uint)buffer.Length)
{
throw new ArgumentOutOfRangeException();
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.length);
}
Unsafe.WriteUnaligned<T>(ref buffer.DangerousGetPinnableReference(), value);
}
Expand All @@ -50,7 +50,7 @@ public static bool TryWriteMachineEndian<T>(Span<byte> buffer, ref T value)
#else
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
{
throw new ArgumentException(SR.Format(SR.Argument_InvalidTypeWithPointersNotSupported, typeof(T)));
ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T));
}
#endif
if (Unsafe.SizeOf<T>() > (uint)buffer.Length)
Expand Down
34 changes: 34 additions & 0 deletions src/System.Memory/src/System/Buffers/OperationStatus.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// 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 System.Buffers
{
/// <summary>
/// This enum defines the various potential status that can be returned from Span-based operations
/// that support processing of input contained in multiple discontiguous buffers.
/// </summary>
public enum OperationStatus
{
/// <summary>
/// The entire input buffer has been processed and the operation is complete.
/// </summary>
Done,
/// <summary>
/// The input is partially processed, up to what could fit into the destination buffer.
/// The caller can enlarge the destination buffer, slice the buffers appropriately, and retry.
/// </summary>
DestinationTooSmall,
/// <summary>
/// The input is partially processed, up to the last valid chunk of the input that could be consumed.
/// The caller can stitch the remaining unprocessed input with more data, slice the buffers appropriately, and retry.
/// </summary>
NeedMoreData,
/// <summary>
/// The input contained invalid bytes which could not be processed. If the input is partially processed,
/// the destination contains the partial result. This guarantees that no additional data appended to the input
/// will make the invalid sequence valid.
/// </summary>
InvalidData,
}
}
Loading