Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add netstandard2.0 to the targets #112

Merged
merged 4 commits into from
Nov 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/ZLogger/Formatters/PlainTextZLoggerFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,17 +98,17 @@ static void Write(IBufferWriter<byte> writer, ReadOnlySpan<byte> message1, strin
{
var span = writer.GetSpan(message1.Length + Encoding.UTF8.GetMaxByteCount(message2.Length));
message1.CopyTo(span);
var written2 = Encoding.UTF8.GetBytes(message2, span.Slice(message1.Length));
var written2 = Encoding.UTF8.GetBytes(message2.AsSpan(), span.Slice(message1.Length));
writer.Advance(message1.Length + written2);
}

static void Write(IBufferWriter<byte> writer, string message1, string message2, string message3)
{
var span = writer.GetSpan(Encoding.UTF8.GetMaxByteCount(message1.Length + message2.Length + message3.Length));

var written1 = Encoding.UTF8.GetBytes(message1, span);
var written2 = Encoding.UTF8.GetBytes(message2, span.Slice(written1));
var written3 = Encoding.UTF8.GetBytes(message3, span.Slice(written1 + written2));
var written1 = Encoding.UTF8.GetBytes(message1.AsSpan(), span);
var written2 = Encoding.UTF8.GetBytes(message2.AsSpan(), span.Slice(written1));
var written3 = Encoding.UTF8.GetBytes(message3.AsSpan(), span.Slice(written1 + written2));
writer.Advance(written1 + written2 + written3);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/ZLogger/Formatters/SystemTextJsonZLoggerFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public void FormatLogEntry<TEntry>(IBufferWriter<byte> writer, TEntry entry) whe
// If `BeginScope(format, arg1, arg2)` style is used, the first argument `format` string is passed with this name
if (x.Key == "{OriginalFormat}") continue;

WriteMutatedJsonKeyName(x.Key, jsonWriter, KeyNameMutator);
WriteMutatedJsonKeyName(x.Key.AsSpan(), jsonWriter, KeyNameMutator);

if (x.Value is { } value)
{
Expand Down
27 changes: 13 additions & 14 deletions src/ZLogger/Internal/EnumDictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,14 @@ public static EnumDictionary Create<T>()
{
// dictionary key is enumValue, value is name.
var unboxedEnumValue = (T)enumValue;
var key = MemoryMarshal.CreateReadOnlySpan(ref Unsafe.As<T, byte>(ref unboxedEnumValue), Unsafe.SizeOf<T>()).ToArray();

var keySpan =
#if NETSTANDARD2_0
Shims.CreateReadOnlySpan(ref Unsafe.As<T, byte>(ref unboxedEnumValue), Unsafe.SizeOf<T>());
#else
MemoryMarshal.CreateReadOnlySpan(ref Unsafe.As<T, byte>(ref unboxedEnumValue), Unsafe.SizeOf<T>());
#endif
var key = keySpan.ToArray();

var value1 = Encoding.UTF8.GetBytes(name);
var value2 = JsonEncodedText.Encode(value1);
Expand Down Expand Up @@ -154,20 +161,12 @@ static int GetBytesHashCode(ReadOnlySpan<byte> bytes)
}
}

readonly struct Entry
readonly struct Entry(byte[] key, string name, byte[] utf8Name, JsonEncodedText jsonEncoded)
{
public readonly byte[] Key;
public readonly string Name;
public readonly byte[] Utf8Name;
public readonly JsonEncodedText JsonEncoded;

public Entry(byte[] key, string name, byte[] utf8Name, JsonEncodedText jsonEncoded)
{
Key = key;
Name = name;
Utf8Name = utf8Name;
JsonEncoded = jsonEncoded;
}
public readonly byte[] Key = key;
public readonly string Name = name;
public readonly byte[] Utf8Name = utf8Name;
public readonly JsonEncodedText JsonEncoded = jsonEncoded;

// for debugging
public override string ToString()
Expand Down
64 changes: 58 additions & 6 deletions src/ZLogger/Internal/MagicalBox.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Buffers;
using System;
using System.Buffers;
using System.Collections.Concurrent;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
Expand All @@ -23,7 +24,7 @@ public MagicalBox(byte[] storage)

public bool TryWrite<T>(T value, out int offset)
{
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
if (!IsSupportedType<T>())
{
offset = 0;
return false;
Expand All @@ -47,7 +48,7 @@ public bool TryWrite<T>(T value, out int offset)

public bool TryRead<T>(int offset, out T value)
{
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>()
if (!IsSupportedType<T>()
|| offset < 0
|| (storage.Length < offset + Unsafe.SizeOf<T>()))
{
Expand Down Expand Up @@ -77,7 +78,11 @@ public T Read<T>(int offset)
public ReadOnlySpan<byte> ReadRawEnumValue(Type type, int offset)
{
var (_, size, _) = ReaderCache.GetEnumDictionaryAndValueSize(type);
#if NETSTANDARD2_0
return Shims.CreateReadOnlySpan(ref storage[offset], size);
#else
return MemoryMarshal.CreateReadOnlySpan(ref storage[offset], size);
#endif
}

public bool TryReadTo(Type type, int offset, int alignment, string? format, ref Utf8StringWriter<IBufferWriter<byte>> handler)
Expand Down Expand Up @@ -136,7 +141,12 @@ public bool TryReadTo(Type type, int offset, int alignment, string? format, ref
if (type.IsEnum)
{
var (dict, size, converter) = ReaderCache.GetEnumDictionaryAndValueSize(type);
var rawValue = MemoryMarshal.CreateReadOnlySpan(ref storage[offset], size);
var rawValue =
#if NETSTANDARD2_0
Shims.CreateReadOnlySpan(ref storage[offset], size);
#else
MemoryMarshal.CreateReadOnlySpan(ref storage[offset], size);
#endif
var name = dict.GetUtf8Name(rawValue);
if (name == null)
{
Expand Down Expand Up @@ -234,7 +244,11 @@ public bool TryReadTo(Type type, int offset, int alignment, string? format, ref
if (type.IsEnum)
{
var (dict, size, converter) = ReaderCache.GetEnumDictionaryAndValueSize(type);
#if NETSTANDARD2_0
var rawValue = Shims.CreateReadOnlySpan(ref storage[offset], size);
#else
var rawValue = MemoryMarshal.CreateReadOnlySpan(ref storage[offset], size);
#endif
var name = dict.GetStringName(rawValue);
if (name == null)
{
Expand Down Expand Up @@ -334,7 +348,12 @@ public bool TryReadTo(Type type, int offset, Utf8JsonWriter jsonWriter)
if (type.IsEnum)
{
var (dict, size, converter) = ReaderCache.GetEnumDictionaryAndValueSize(type);
var rawValue = MemoryMarshal.CreateReadOnlySpan(ref storage[offset], size);
var rawValue =
#if NETSTANDARD2_0
Shims.CreateReadOnlySpan(ref storage[offset], size);
#else
MemoryMarshal.CreateReadOnlySpan(ref storage[offset], size);
#endif
var name = dict.GetJsonEncodedName(rawValue);
if (name == null)
{
Expand Down Expand Up @@ -362,6 +381,39 @@ public bool TryReadTo(Type type, int offset, Utf8JsonWriter jsonWriter)
return true;
}

static bool IsSupportedType<T>()
{
#if NETSTANDARD2_0
var type = typeof(T);
var code = Type.GetTypeCode(type);
switch (code)
{
case TypeCode.Boolean:
case TypeCode.Byte:
case TypeCode.Char:
case TypeCode.DateTime:
case TypeCode.Decimal:
case TypeCode.Double:
case TypeCode.Int16:
case TypeCode.Int32:
case TypeCode.Int64:
case TypeCode.SByte:
case TypeCode.Single:
case TypeCode.UInt16:
case TypeCode.UInt32:
case TypeCode.UInt64:
return true;
}
if (type.IsEnum || type == typeof(Guid) || type == typeof(DateTimeOffset))
{
return true;
}
return false;
#else
return !RuntimeHelpers.IsReferenceOrContainsReferences<T>();
#endif
}

static void ThrowArgumentOutOfRangeException()
{
throw new ArgumentOutOfRangeException();
Expand Down Expand Up @@ -391,7 +443,7 @@ static class ReaderCache<T>
{
static ReaderCache()
{
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
if (!IsSupportedType<T>())
{
ReaderCache.readCache.TryAdd(typeof(T), null);
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace System.Runtime.CompilerServices;

/// <summary>Provides a handler used by the language compiler to process interpolated strings into <see cref="string"/> instances.</summary>
[InterpolatedStringHandler]
public ref struct DefaultInterpolatedStringHandler
internal ref struct DefaultInterpolatedStringHandler
{
// Implementation note:
// As this type lives in CompilerServices and is only intended to be targeted by the compiler,
Expand Down Expand Up @@ -94,7 +94,7 @@ internal static int GetDefaultLength(int literalLength, int formattedCount) =>

/// <summary>Gets the built <see cref="string"/>.</summary>
/// <returns>The built string.</returns>
public override string ToString() => new string(Text);
public override string ToString() => Text.ToString();

/// <summary>Gets the built <see cref="string"/> and clears the handler.</summary>
/// <returns>The built string.</returns>
Expand All @@ -106,7 +106,7 @@ internal static int GetDefaultLength(int literalLength, int formattedCount) =>
/// </remarks>
public string ToStringAndClear()
{
string result = new string(Text);
string result = Text.ToString();
Clear();
return result;
}
Expand Down Expand Up @@ -627,7 +627,7 @@ private void GrowCore(uint requiredMinCapacity)

// uint newCapacity = Math.Max(requiredMinCapacity, Math.Min((uint)_chars.Length * 2, string.MaxLength));
uint newCapacity = Math.Max(requiredMinCapacity, Math.Min((uint)_chars.Length * 2, 0x3FFFFFDF));
int arraySize = (int)Math.Clamp(newCapacity, MinimumArrayPoolLength, int.MaxValue);
var arraySize = (int)Math.Max(Math.Min(newCapacity, int.MaxValue), MinimumArrayPoolLength);

char[] newArray = ArrayPool<char>.Shared.Rent(arraySize);
_chars.Slice(0, _pos).CopyTo(newArray);
Expand Down
36 changes: 36 additions & 0 deletions src/ZLogger/Internal/Shims/Shims.NetStandard2.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#if NETSTANDARD2_0
using System.Text;

namespace ZLogger;

internal static partial class Shims
{
public static int GetBytes(this Encoding encoding, ReadOnlySpan<char> chars, ReadOnlySpan<byte> bytes)
{
unsafe
{
fixed (char* charsPtr = &chars[0])
fixed (byte* bytesPtr = &bytes[0])
{
return encoding.GetBytes(charsPtr, chars.Length, bytesPtr, bytes.Length);
}
}
}

public static unsafe Span<T> CreateSpan<T>(ref T value, int length) where T : unmanaged
{
fixed(T* pointer = &value)
{
return new Span<T>(pointer, length);
}
}

public static unsafe ReadOnlySpan<T> CreateReadOnlySpan<T>(ref T value, int length) where T : unmanaged
{
fixed(T* pointer = &value)
{
return new ReadOnlySpan<T>(pointer, length);
}
}
}
#endif
4 changes: 2 additions & 2 deletions src/ZLogger/LogStates/InterpolatedStringLogState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public void WriteJsonParameterKeyValues(Utf8JsonWriter jsonWriter, JsonSerialize
for (var i = 0; i < ParameterCount; i++)
{
ref var p = ref parameters[i];
SystemTextJsonZLoggerFormatter.WriteMutatedJsonKeyName(p.Name, jsonWriter, keyNameMutator);
SystemTextJsonZLoggerFormatter.WriteMutatedJsonKeyName(p.Name.AsSpan(), jsonWriter, keyNameMutator);

if (magicalBox.TryReadTo(p.Type, p.BoxOffset, jsonWriter))
{
Expand All @@ -119,7 +119,7 @@ public ReadOnlySpan<byte> GetParameterKey(int index)

public ReadOnlySpan<char> GetParameterKeyAsString(int index)
{
return parameters[index].Name;
return parameters[index].Name.AsSpan();
}

public object? GetParameterValue(int index)
Expand Down
2 changes: 1 addition & 1 deletion src/ZLogger/LogStates/StringFormatterLogState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public ReadOnlySpan<char> GetParameterKeyAsString(int index)
{
if (originalStateParameters != null)
{
return originalStateParameters[index].Key;
return originalStateParameters[index].Key.AsSpan();
}
throw new IndexOutOfRangeException(nameof(index));
}
Expand Down
6 changes: 3 additions & 3 deletions src/ZLogger/ZLogger.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.1;net6.0;net8.0</TargetFrameworks>
<TargetFrameworks>netstandard2.0;netstandard2.1;net6.0;net8.0</TargetFrameworks>
<Nullable>enable</Nullable>
<LangVersion>12.0</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
Expand All @@ -24,14 +24,14 @@
<PackageReference Include="Microsoft.Extensions.Logging.Configuration" Version="8.0.0" />
<PackageReference Include="System.Threading.Channels" Version="8.0.0" />
<PackageReference Include="System.IO.Hashing" Version="8.0.0" />
<PackageReference Include="Utf8StringInterpolation" Version="1.1.0" />
<PackageReference Include="Utf8StringInterpolation" Version="1.2.0" />
</ItemGroup>

<ItemGroup Condition="$(TargetFramework) == 'net6.0'">
<PackageReference Include="Microsoft.Bcl.TimeProvider" Version="8.0.0" />
</ItemGroup>

<ItemGroup Condition="$(TargetFramework) == 'netstandard2.1'">
<ItemGroup Condition="$(TargetFramework) == 'netstandard2.0' Or $(TargetFramework) == 'netstandard2.1'">
<PackageReference Include="System.Text.Json" Version="8.0.0" />
<PackageReference Include="Microsoft.Bcl.TimeProvider" Version="8.0.0" />
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0" />
Expand Down
9 changes: 9 additions & 0 deletions src/ZLogger/ZLoggerInterpolatedStringHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -285,9 +285,18 @@ public bool Equals(LiteralList other)
// convert const strings as address sequence
static ReadOnlySpan<byte> AsBytes(ReadOnlySpan<string?> literals)
{
#if NETSTANDARD2_0
if (literals.IsEmpty)
return default;

return Shims.CreateSpan(
ref Unsafe.As<string?, byte>(ref Unsafe.AsRef(in literals[0])),
literals.Length * Unsafe.SizeOf<string>());
#else
return MemoryMarshal.CreateSpan(
ref Unsafe.As<string?, byte>(ref MemoryMarshal.GetReference(literals)),
literals.Length * Unsafe.SizeOf<string>());
#endif
}
}
}
Expand Down
Loading