diff --git a/QRCoder/Attributes/NotNullWhenAttribute.cs b/QRCoder/Attributes/NotNullWhenAttribute.cs index 3cc3ce1c..258826ac 100644 --- a/QRCoder/Attributes/NotNullWhenAttribute.cs +++ b/QRCoder/Attributes/NotNullWhenAttribute.cs @@ -1,4 +1,4 @@ -#if !NETCOREAPP +#if !NETCOREAPP && !NETSTANDARD2_1 namespace System.Diagnostics.CodeAnalysis; /// diff --git a/QRCoder/PngByteQRCode.cs b/QRCoder/PngByteQRCode.cs index 2ad015b7..297712e5 100644 --- a/QRCoder/PngByteQRCode.cs +++ b/QRCoder/PngByteQRCode.cs @@ -1,4 +1,4 @@ -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1 +#if HAS_SPAN using System.Buffers; #endif using System; @@ -41,7 +41,7 @@ public byte[] GetGraphic(int pixelsPerModule, bool drawQuietZones = true) png.WriteHeader(size, size, 1, PngBuilder.ColorType.Greyscale); var scanLines = DrawScanlines(pixelsPerModule, drawQuietZones); png.WriteScanlines(scanLines); -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1 +#if HAS_SPAN ArrayPool.Shared.Return(scanLines.Array!); #endif png.WriteEnd(); @@ -77,7 +77,7 @@ public byte[] GetGraphic(int pixelsPerModule, byte[] darkColorRgba, byte[] light png.WritePalette(darkColorRgba, lightColorRgba); var scanLines = DrawScanlines(pixelsPerModule, drawQuietZones); png.WriteScanlines(scanLines); -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1 +#if HAS_SPAN ArrayPool.Shared.Return(scanLines.Array!); #endif png.WriteEnd(); @@ -97,7 +97,7 @@ private ArraySegment DrawScanlines(int pixelsPerModule, bool drawQuietZone var quietZoneOffset = (drawQuietZones ? 0 : 4); var bytesPerScanline = (matrixSize * pixelsPerModule + 7) / 8 + 1; // A monochrome scanline is one byte for filter type then one bit per pixel. var scanLinesLength = bytesPerScanline * matrixSize * pixelsPerModule; -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1 +#if HAS_SPAN var scanlines = ArrayPool.Shared.Rent(scanLinesLength); Array.Clear(scanlines, 0, scanLinesLength); #else diff --git a/QRCoder/QRCodeData.cs b/QRCoder/QRCodeData.cs index ffd2ca8b..10a7a67b 100644 --- a/QRCoder/QRCodeData.cs +++ b/QRCoder/QRCodeData.cs @@ -152,7 +152,7 @@ public byte[] GetRawData(Compression compressMode) try { //Add header - signature ("QRR") -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1 +#if HAS_SPAN targetStream.Write([0x51, 0x52, 0x52, 0x00]); #else targetStream.Write(new byte[] { 0x51, 0x52, 0x52, 0x00 }, 0, 4); diff --git a/QRCoder/QRCodeGenerator.cs b/QRCoder/QRCodeGenerator.cs index 3c598f8e..40890d5e 100644 --- a/QRCoder/QRCodeGenerator.cs +++ b/QRCoder/QRCodeGenerator.cs @@ -1,5 +1,5 @@ using System; -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1 +#if HAS_SPAN using System.Buffers; #endif using System.Collections; @@ -586,7 +586,7 @@ private static void TrimLeadingZeros(BitArray fStrEcc, ref int index, ref int co private static void ShiftTowardsBit0(BitArray fStrEcc, int num) { -#if NETCOREAPP +#if HAS_SPAN fStrEcc.RightShift(num); // Shift towards bit 0 #else for (var i = 0; i < fStrEcc.Length - num; i++) @@ -598,7 +598,7 @@ private static void ShiftTowardsBit0(BitArray fStrEcc, int num) private static void ShiftAwayFromBit0(BitArray fStrEcc, int num) { -#if NETCOREAPP +#if HAS_SPAN fStrEcc.LeftShift(num); // Shift away from bit 0 #else for (var i = fStrEcc.Length - 1; i >= num; i--) @@ -697,7 +697,7 @@ private static ArraySegment CalculateECCWords(BitArray bitArray, int offse generatorPolynom.Dispose(); // Convert the resulting polynomial into a byte array representing the ECC codewords. -#if NETCOREAPP +#if HAS_SPAN var array = ArrayPool.Shared.Rent(leadTermSource.Count); var ret = new ArraySegment(array, 0, leadTermSource.Count); #else @@ -1009,7 +1009,7 @@ private static BitArray PlainTextToBinaryNumeric(string plainText) for (int i = 0; i < plainText.Length - 2; i += 3) { // Parse the next three characters as a decimal integer. -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1 +#if HAS_SPAN var dec = int.Parse(plainText.AsSpan(i, 3), NumberStyles.None, CultureInfo.InvariantCulture); #else var dec = int.Parse(plainText.Substring(i, 3), NumberStyles.None, CultureInfo.InvariantCulture); @@ -1021,7 +1021,7 @@ private static BitArray PlainTextToBinaryNumeric(string plainText) // Handle any remaining digits if the total number is not a multiple of three. if (plainText.Length % 3 == 2) // Two remaining digits are encoded in 7 bits. { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1 +#if HAS_SPAN var dec = int.Parse(plainText.AsSpan(plainText.Length / 3 * 3, 2), NumberStyles.None, CultureInfo.InvariantCulture); #else var dec = int.Parse(plainText.Substring(plainText.Length / 3 * 3, 2), NumberStyles.None, CultureInfo.InvariantCulture); @@ -1030,7 +1030,7 @@ private static BitArray PlainTextToBinaryNumeric(string plainText) } else if (plainText.Length % 3 == 1) // One remaining digit is encoded in 4 bits. { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1 +#if HAS_SPAN var dec = int.Parse(plainText.AsSpan(plainText.Length / 3 * 3, 1), NumberStyles.None, CultureInfo.InvariantCulture); #else var dec = int.Parse(plainText.Substring(plainText.Length / 3 * 3, 1), NumberStyles.None, CultureInfo.InvariantCulture); @@ -1101,7 +1101,7 @@ private static BitArray PlainTextToBinaryByte(string plainText, EciMode eciMode, } } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1 +#if HAS_SPAN // We can use stackalloc for small arrays to prevent heap allocations const int MAX_STACK_SIZE_IN_BYTES = 512; @@ -1132,7 +1132,7 @@ private static BitArray PlainTextToBinaryByte(string plainText, EciMode eciMode, bitArray = ToBitArray(codeBytes); } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1 +#if HAS_SPAN if (bufferFromPool != null) ArrayPool.Shared.Return(bufferFromPool); #endif @@ -1148,7 +1148,7 @@ private static BitArray PlainTextToBinaryByte(string plainText, EciMode eciMode, /// The number of leading zeros to prepend to the resulting BitArray. /// A BitArray representing the bits of the input byteArray, with optional leading zeros. private static BitArray ToBitArray( -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1 +#if HAS_SPAN ReadOnlySpan byteArray, // byte[] has an implicit cast to ReadOnlySpan #else byte[] byteArray, @@ -1250,7 +1250,7 @@ private static Polynom MultiplyAlphaPolynoms(Polynom polynomBase, Polynom polyno } // Identify and merge terms with the same exponent. -#if NETCOREAPP +#if NET5_0_OR_GREATER var toGlue = GetNotUniqueExponents(resultPolynom, resultPolynom.Count <= 128 ? stackalloc int[128].Slice(0, resultPolynom.Count) : new int[resultPolynom.Count]); var gluedPolynoms = toGlue.Length <= 128 ? stackalloc PolynomItem[128].Slice(0, toGlue.Length) @@ -1276,7 +1276,7 @@ private static Polynom MultiplyAlphaPolynoms(Polynom polynomBase, Polynom polyno // Remove duplicated exponents and add the corrected ones back. for (int i = resultPolynom.Count - 1; i >= 0; i--) -#if NETCOREAPP +#if NET5_0_OR_GREATER if (toGlue.Contains(resultPolynom[i].Exponent)) #else if (Array.IndexOf(toGlue, resultPolynom[i].Exponent) >= 0) @@ -1290,7 +1290,7 @@ private static Polynom MultiplyAlphaPolynoms(Polynom polynomBase, Polynom polyno return resultPolynom; // Auxiliary function to identify exponents that appear more than once in the polynomial. -#if NETCOREAPP +#if NET5_0_OR_GREATER static ReadOnlySpan GetNotUniqueExponents(Polynom list, Span buffer) { // It works as follows: diff --git a/QRCoder/QRCodeGenerator/CodewordBlock.cs b/QRCoder/QRCodeGenerator/CodewordBlock.cs index 63c52115..7cf78577 100644 --- a/QRCoder/QRCodeGenerator/CodewordBlock.cs +++ b/QRCoder/QRCodeGenerator/CodewordBlock.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Threading; -#if NETCOREAPP +#if HAS_SPAN using System.Buffers; #endif @@ -51,7 +51,7 @@ public static List GetList(int capacity) public static void ReturnList(List list) { -#if NETCOREAPP +#if HAS_SPAN foreach (var item in list) { ArrayPool.Shared.Return(item.ECCWords.Array!); diff --git a/QRCoder/QRCodeGenerator/Polynom.cs b/QRCoder/QRCodeGenerator/Polynom.cs index 6cb6115d..cc904c7f 100644 --- a/QRCoder/QRCodeGenerator/Polynom.cs +++ b/QRCoder/QRCodeGenerator/Polynom.cs @@ -197,7 +197,7 @@ private void AssertCapacity(int min) void ThrowNotSupportedException() => throw new NotSupportedException("The polynomial capacity is fixed and cannot be increased."); } -#if NETCOREAPP +#if HAS_SPAN /// /// Rents memory for the polynomial terms from the shared memory pool. /// diff --git a/QRCoder/QRCoder.csproj b/QRCoder/QRCoder.csproj index cae73ca4..ed8fc4d6 100644 --- a/QRCoder/QRCoder.csproj +++ b/QRCoder/QRCoder.csproj @@ -1,11 +1,12 @@  - net35;net40;netstandard1.3;netstandard2.0;net5.0;net5.0-windows;net6.0;net6.0-windows + net35;net40;netstandard1.3;netstandard2.0;netstandard2.1;net5.0;net5.0-windows;net6.0;net6.0-windows false $(DefineConstants);SYSTEM_DRAWING $(DefineConstants);NET5_0_WINDOWS $(DefineConstants);NET6_0_WINDOWS + $(DefineConstants);HAS_SPAN true true $(WarningsAsErrors);CS1591 @@ -38,17 +39,17 @@ - + - + - + diff --git a/QRCoderApiTests/net35+net40+net50+net50-windows+netstandard20/QRCoder.approved.txt b/QRCoderApiTests/net35+net40+net50+net50-windows+netstandard20+netstandard21/QRCoder.approved.txt similarity index 100% rename from QRCoderApiTests/net35+net40+net50+net50-windows+netstandard20/QRCoder.approved.txt rename to QRCoderApiTests/net35+net40+net50+net50-windows+netstandard20+netstandard21/QRCoder.approved.txt