diff --git a/.editorconfig b/.editorconfig
index f68d0e5c..a74b74d2 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -263,4 +263,4 @@ dotnet_diagnostic.IDE0005.severity = warning
# Enforce formatting https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/formatting-rules#rule-id-ide0055-fix-formatting
dotnet_diagnostic.IDE0055.severity = error
dotnet_diagnostic.IDE1006.severity = error
-dotnet_diagnostic.IDE0022.severity = error
+dotnet_diagnostic.IDE0022.severity = none
diff --git a/Directory.Build.props b/Directory.Build.props
index 50156e31..4a218b7a 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -40,7 +40,7 @@
true
$(NoWarn);IDE0005
True
- None
+ Recommended
diff --git a/QRCoder/ASCIIQRCode.cs b/QRCoder/ASCIIQRCode.cs
index 84ea3b99..dedadb08 100644
--- a/QRCoder/ASCIIQRCode.cs
+++ b/QRCoder/ASCIIQRCode.cs
@@ -31,7 +31,7 @@ public AsciiQRCode(QRCodeData data) : base(data) { }
public string GetGraphic(int repeatPerModule, string darkColorString = "██", string whiteSpaceString = " ", bool drawQuietZones = true, string endOfLine = "\n")
{
if (repeatPerModule < 1)
- throw new Exception("The repeatPerModule-parameter must be 1 or greater.");
+ throw new ArgumentOutOfRangeException(nameof(repeatPerModule), "The repeatPerModule parameter must be 1 or greater.");
return string.Join(endOfLine, GetLineByLineGraphic(repeatPerModule, darkColorString, whiteSpaceString, drawQuietZones));
}
diff --git a/QRCoder/ArtQRCode.cs b/QRCoder/ArtQRCode.cs
index 225b18eb..7ace0d9b 100644
--- a/QRCoder/ArtQRCode.cs
+++ b/QRCoder/ArtQRCode.cs
@@ -63,7 +63,7 @@ public Bitmap GetGraphic(int pixelsPerModule, Color darkColor, Color lightColor,
BackgroundImageStyle backgroundImageStyle = BackgroundImageStyle.DataAreaOnly, Bitmap? finderPatternImage = null)
{
if (pixelSizeFactor > 1)
- throw new Exception("The parameter pixelSize must be between 0 and 1. (0-100%)");
+ throw new ArgumentOutOfRangeException(nameof(pixelSizeFactor), "The parameter pixelSizeFactor must be between 0 and 1. (0-100%)");
int pixelSize = (int)Math.Min(pixelsPerModule, Math.Floor(pixelsPerModule * pixelSizeFactor));
var numModules = QrCodeData.ModuleMatrix.Count - (drawQuietZones ? 0 : 8);
@@ -134,7 +134,7 @@ public Bitmap GetGraphic(int pixelsPerModule, Color darkColor, Color lightColor,
/// Size of the dots
/// Color of the pixels
///
- private Bitmap MakeDotPixel(int pixelsPerModule, int pixelSize, SolidBrush brush)
+ private static Bitmap MakeDotPixel(int pixelsPerModule, int pixelSize, SolidBrush brush)
{
// draw a dot
var bitmap = new Bitmap(pixelSize, pixelSize);
@@ -168,7 +168,7 @@ private Bitmap MakeDotPixel(int pixelsPerModule, int pixelSize, SolidBrush brush
/// Y position
/// Total number of modules per row
/// true, if position is part of quiet zone
- private bool IsPartOfQuietZone(int x, int y, int numModules)
+ private static bool IsPartOfQuietZone(int x, int y, int numModules)
{
return
x < 4 || //left
@@ -186,7 +186,7 @@ private bool IsPartOfQuietZone(int x, int y, int numModules)
/// Total number of modules per row
/// Offset in modules (usually depending on drawQuietZones parameter)
/// true, if position is part of any finder pattern
- private bool IsPartOfFinderPattern(int x, int y, int numModules, int offset)
+ private static bool IsPartOfFinderPattern(int x, int y, int numModules, int offset)
{
var cornerSize = 11 - offset;
var outerLimitLow = (numModules - cornerSize - 1);
@@ -204,7 +204,7 @@ private bool IsPartOfFinderPattern(int x, int y, int numModules, int offset)
///
///
/// Resized image as bitmap
- private Bitmap Resize(Bitmap image, int newSize)
+ private static Bitmap Resize(Bitmap image, int newSize)
{
float scale = Math.Min((float)newSize / image.Width, (float)newSize / image.Height);
var scaledWidth = (int)(image.Width * scale);
diff --git a/QRCoder/Base64QRCode.cs b/QRCoder/Base64QRCode.cs
index b5e1cc3a..166cc49f 100644
--- a/QRCoder/Base64QRCode.cs
+++ b/QRCoder/Base64QRCode.cs
@@ -141,7 +141,7 @@ public string GetGraphic(int pixelsPerModule, Color darkColor, Color lightColor,
#if NET6_0_OR_GREATER
[System.Runtime.Versioning.SupportedOSPlatform("windows")]
#endif
- private string BitmapToBase64(Bitmap bmp, ImageType imgType)
+ private static string BitmapToBase64(Bitmap bmp, ImageType imgType)
{
var iFormat = imgType switch
{
diff --git a/QRCoder/BitmapByteQRCode.cs b/QRCoder/BitmapByteQRCode.cs
index 46d3d584..0ca6c5ed 100644
--- a/QRCoder/BitmapByteQRCode.cs
+++ b/QRCoder/BitmapByteQRCode.cs
@@ -41,7 +41,7 @@ public byte[] GetGraphic(int pixelsPerModule)
/// The color of the light modules in HTML hex format.
/// Returns the QR code graphic as a bitmap byte array.
public byte[] GetGraphic(int pixelsPerModule, string darkColorHtmlHex, string lightColorHtmlHex)
- => GetGraphic(pixelsPerModule, HexColorToByteArray(darkColorHtmlHex), HexColorToByteArray(lightColorHtmlHex));
+ => GetGraphic(pixelsPerModule, darkColorHtmlHex.HexColorToByteArray(), lightColorHtmlHex.HexColorToByteArray());
///
/// Returns the QR code graphic as a bitmap byte array.
@@ -134,29 +134,13 @@ public byte[] GetGraphic(int pixelsPerModule, byte[] darkColorRgb, byte[] lightC
}
- ///
- /// Converts a hex color string to a byte array.
- ///
- /// The hex color string to convert.
- /// Returns the color as a byte array.
- private byte[] HexColorToByteArray(string colorString)
- {
- if (colorString.StartsWith("#"))
- colorString = colorString.Substring(1);
- byte[] byteColor = new byte[colorString.Length / 2];
- for (int i = 0; i < byteColor.Length; i++)
- byteColor[i] = byte.Parse(colorString.Substring(i * 2, 2), System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture);
- return byteColor;
- }
-
-
///
/// Converts an integer to a 4 bytes and writes them to a byte array at given position
///
/// The integer to convert.
/// Index of destinationArray where the converted bytes are written to
/// Destination byte array that receives the bytes
- private void CopyIntAs4ByteToArray(int inp, int destinationIndex, byte[] destinationArray)
+ private static void CopyIntAs4ByteToArray(int inp, int destinationIndex, byte[] destinationArray)
{
unchecked
{
diff --git a/QRCoder/Extensions/StringExtensions.cs b/QRCoder/Extensions/StringExtensions.cs
index 702c074e..6dcbb292 100644
--- a/QRCoder/Extensions/StringExtensions.cs
+++ b/QRCoder/Extensions/StringExtensions.cs
@@ -29,4 +29,30 @@ public static bool IsNullOrWhiteSpace(
return string.IsNullOrWhiteSpace(value);
#endif
}
+
+ ///
+ /// Converts a hex color string to a byte array.
+ ///
+ /// Color in HEX format like #ffffff.
+ /// Returns the color as a byte array.
+ internal static byte[] HexColorToByteArray(this string colorString)
+ {
+ var offset = 0;
+ if (colorString.StartsWith("#", StringComparison.Ordinal))
+ offset = 1;
+ byte[] byteColor = new byte[(colorString.Length - offset) / 2];
+ for (int i = 0; i < byteColor.Length; i++)
+#if HAS_SPAN
+ byteColor[i] = byte.Parse(colorString.AsSpan(i * 2 + offset, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture);
+#else
+ byteColor[i] = byte.Parse(colorString.Substring(i * 2 + offset, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture);
+#endif
+ return byteColor;
+ }
+
+#if NETSTANDARD1_3
+ ///
+ internal static string ToString(this char c, CultureInfo _)
+ => c.ToString();
+#endif
}
diff --git a/QRCoder/Extensions/StringValueAttribute.cs b/QRCoder/Extensions/StringValueAttribute.cs
index dcb9b731..ca93b888 100644
--- a/QRCoder/Extensions/StringValueAttribute.cs
+++ b/QRCoder/Extensions/StringValueAttribute.cs
@@ -7,6 +7,7 @@ namespace QRCoder.Extensions;
/// Used to represent a string value for a value in an enum
///
[Obsolete("This attribute will be removed in a future version of QRCoder.")]
+[AttributeUsage(AttributeTargets.Field)]
public class StringValueAttribute : Attribute
{
diff --git a/QRCoder/PayloadGenerator.cs b/QRCoder/PayloadGenerator.cs
index ce465401..003882ee 100644
--- a/QRCoder/PayloadGenerator.cs
+++ b/QRCoder/PayloadGenerator.cs
@@ -17,20 +17,24 @@ public static partial class PayloadGenerator
private static bool IsValidIban(string iban)
{
//Clean IBAN
- var ibanCleared = iban.ToUpper().Replace(" ", "").Replace("-", "");
+ var ibanCleared = iban.ToUpperInvariant().Replace(" ", "").Replace("-", "");
//Check for general structure
var structurallyValid = Regex.IsMatch(ibanCleared, @"^[a-zA-Z]{2}[0-9]{2}([a-zA-Z0-9]?){16,30}$");
//Check IBAN checksum
var checksumValid = false;
- var sum = $"{ibanCleared.Substring(4)}{ibanCleared.Substring(0, 4)}".ToCharArray().Aggregate("", (current, c) => current + (char.IsLetter(c) ? (c - 55).ToString() : c.ToString()));
+ var sum = $"{ibanCleared.Substring(4)}{ibanCleared.Substring(0, 4)}".ToCharArray().Aggregate("", (current, c) => current + (char.IsLetter(c) ? (c - 55).ToString(CultureInfo.InvariantCulture) : c.ToString(CultureInfo.InvariantCulture)));
int m = 0;
for (int i = 0; i < (int)Math.Ceiling((sum.Length - 2) / 7d); i++)
{
var offset = (i == 0 ? 0 : 2);
var start = i * 7 + offset;
+#if NET5_0_OR_GREATER
+ var n = string.Concat(i == 0 ? "" : m.ToString(CultureInfo.InvariantCulture), sum.AsSpan(start, Math.Min(9 - offset, sum.Length - start)));
+#else
var n = (i == 0 ? "" : m.ToString()) + sum.Substring(start, Math.Min(9 - offset, sum.Length - start));
+#endif
if (!int.TryParse(n, NumberStyles.Any, CultureInfo.InvariantCulture, out m))
break;
m %= 97;
@@ -49,8 +53,8 @@ private static bool IsValidQRIban(string iban)
var foundQrIid = false;
try
{
- var ibanCleared = iban.ToUpper().Replace(" ", "").Replace("-", "");
- var possibleQrIid = Convert.ToInt32(ibanCleared.Substring(4, 5));
+ var ibanCleared = iban.ToUpperInvariant().Replace(" ", "").Replace("-", "");
+ var possibleQrIid = Convert.ToInt32(ibanCleared.Substring(4, 5), CultureInfo.InvariantCulture);
foundQrIid = possibleQrIid >= 30000 && possibleQrIid <= 31999;
}
catch { }
diff --git a/QRCoder/PayloadGenerator/BezahlCode.cs b/QRCoder/PayloadGenerator/BezahlCode.cs
index 50b7354e..7f56bc2e 100644
--- a/QRCoder/PayloadGenerator/BezahlCode.cs
+++ b/QRCoder/PayloadGenerator/BezahlCode.cs
@@ -123,12 +123,12 @@ public BezahlCode(AuthorityType authority, string name, string account, string b
}
else if (internalMode == 2)
{
-#pragma warning disable CS0612
+#pragma warning disable CS0618
if (authority != AuthorityType.periodicsinglepayment && authority != AuthorityType.singledirectdebit && authority != AuthorityType.singlepayment)
throw new BezahlCodeException("The constructor with 'account' and 'bnc' may only be used with 'non SEPA' authority types. Either choose another authority type or switch constructor.");
if (authority == AuthorityType.periodicsinglepayment && (string.IsNullOrEmpty(periodicTimeunit) || periodicTimeunitRotation == 0))
throw new BezahlCodeException("When using 'periodicsinglepayment' as authority type, the parameters 'periodicTimeunit' and 'periodicTimeunitRotation' must be set.");
-#pragma warning restore CS0612
+#pragma warning restore CS0618
}
else if (internalMode == 3)
{
@@ -155,17 +155,17 @@ public BezahlCode(AuthorityType authority, string name, string account, string b
_reason = reason;
//Non-SEPA payment types
-#pragma warning disable CS0612
+#pragma warning disable CS0618
if (authority == AuthorityType.periodicsinglepayment || authority == AuthorityType.singledirectdebit || authority == AuthorityType.singlepayment || authority == AuthorityType.contact || (authority == AuthorityType.contact_v2 && oldWayFilled))
{
-#pragma warning restore CS0612
+#pragma warning restore CS0618
if (!Regex.IsMatch(account.Replace(" ", ""), @"^[0-9]{1,9}$"))
throw new BezahlCodeException("The account entered isn't valid.");
- _account = account.Replace(" ", "").ToUpper();
+ _account = account.Replace(" ", "").ToUpperInvariant();
if (!Regex.IsMatch(bnc.Replace(" ", ""), @"^[0-9]{1,9}$"))
throw new BezahlCodeException("The bnc entered isn't valid.");
- _bnc = bnc.Replace(" ", "").ToUpper();
+ _bnc = bnc.Replace(" ", "").ToUpperInvariant();
if (authority != AuthorityType.contact && authority != AuthorityType.contact_v2)
{
@@ -180,10 +180,10 @@ public BezahlCode(AuthorityType authority, string name, string account, string b
{
if (!IsValidIban(iban))
throw new BezahlCodeException("The IBAN entered isn't valid.");
- _iban = iban.Replace(" ", "").ToUpper();
+ _iban = iban.Replace(" ", "").ToUpperInvariant();
if (!IsValidBic(bic))
throw new BezahlCodeException("The BIC entered isn't valid.");
- _bic = bic.Replace(" ", "").ToUpper();
+ _bic = bic.Replace(" ", "").ToUpperInvariant();
if (authority != AuthorityType.contact_v2)
{
@@ -205,7 +205,7 @@ public BezahlCode(AuthorityType authority, string name, string account, string b
//Checks for all payment types
if (authority != AuthorityType.contact && authority != AuthorityType.contact_v2)
{
- if (amount.ToString().Replace(",", ".").Contains(".") && amount.ToString().Replace(",", ".").Split('.')[1].TrimEnd('0').Length > 2)
+ if (amount.ToString(CultureInfo.InvariantCulture).Contains('.') && amount.ToString(CultureInfo.InvariantCulture).Split('.')[1].TrimEnd('0').Length > 2)
throw new BezahlCodeException("Amount must have less than 3 digits after decimal point.");
if (amount < 0.01m || amount > 999999999.99m)
throw new BezahlCodeException("Amount has to at least 0.01 and must be smaller or equal to 999999999.99.");
@@ -221,11 +221,11 @@ public BezahlCode(AuthorityType authority, string name, string account, string b
throw new BezahlCodeException("Execution date must be today or in future.");
_executionDate = (DateTime)executionDate;
}
-#pragma warning disable CS0612
+#pragma warning disable CS0618
if (authority == AuthorityType.periodicsinglepayment || authority == AuthorityType.periodicsinglepaymentsepa)
-#pragma warning restore CS0612
+#pragma warning restore CS0618
{
- if (periodicTimeunit.ToUpper() != "M" && periodicTimeunit.ToUpper() != "W")
+ if (periodicTimeunit.ToUpperInvariant() != "M" && periodicTimeunit.ToUpperInvariant() != "W")
throw new BezahlCodeException("The periodicTimeunit must be either 'M' (monthly) or 'W' (weekly).");
_periodicTimeunit = periodicTimeunit;
if (periodicTimeunitRotation < 1 || periodicTimeunitRotation > 52)
@@ -253,9 +253,9 @@ public override string ToString()
if (_authority != AuthorityType.contact && _authority != AuthorityType.contact_v2)
{
//Handle what is same for all payments
-#pragma warning disable CS0612
+#pragma warning disable CS0618
if (_authority == AuthorityType.periodicsinglepayment || _authority == AuthorityType.singledirectdebit || _authority == AuthorityType.singlepayment)
-#pragma warning restore CS0612
+#pragma warning restore CS0618
{
bezahlCodePayload += $"account={_account}&";
bezahlCodePayload += $"bnc={_bnc}&";
@@ -277,26 +277,26 @@ public override string ToString()
if (!string.IsNullOrEmpty(_mandateId))
bezahlCodePayload += $"mandateid={Uri.EscapeDataString(_mandateId)}&";
if (_dateOfSignature != DateTime.MinValue)
- bezahlCodePayload += $"dateofsignature={_dateOfSignature.ToString("ddMMyyyy")}&";
+ bezahlCodePayload += $"dateofsignature={_dateOfSignature.ToString("ddMMyyyy", CultureInfo.InvariantCulture)}&";
}
}
- bezahlCodePayload += $"amount={_amount:0.00}&".Replace(".", ",");
+ bezahlCodePayload += string.Format(CultureInfo.InvariantCulture, "amount={0:0.00}&", _amount).Replace(".", ",");
if (!string.IsNullOrEmpty(_reason))
bezahlCodePayload += $"reason={Uri.EscapeDataString(_reason)}&";
bezahlCodePayload += $"currency={_currency}&";
- bezahlCodePayload += $"executiondate={_executionDate.ToString("ddMMyyyy")}&";
-#pragma warning disable CS0612
+ bezahlCodePayload += $"executiondate={_executionDate.ToString("ddMMyyyy", CultureInfo.InvariantCulture)}&";
+#pragma warning disable CS0618
if (_authority == AuthorityType.periodicsinglepayment || _authority == AuthorityType.periodicsinglepaymentsepa)
{
bezahlCodePayload += $"periodictimeunit={_periodicTimeunit}&";
bezahlCodePayload += $"periodictimeunitrotation={_periodicTimeunitRotation}&";
if (_periodicFirstExecutionDate != DateTime.MinValue)
- bezahlCodePayload += $"periodicfirstexecutiondate={_periodicFirstExecutionDate.ToString("ddMMyyyy")}&";
+ bezahlCodePayload += $"periodicfirstexecutiondate={_periodicFirstExecutionDate.ToString("ddMMyyyy", CultureInfo.InvariantCulture)}&";
if (_periodicLastExecutionDate != DateTime.MinValue)
- bezahlCodePayload += $"periodiclastexecutiondate={_periodicLastExecutionDate.ToString("ddMMyyyy")}&";
+ bezahlCodePayload += $"periodiclastexecutiondate={_periodicLastExecutionDate.ToString("ddMMyyyy", CultureInfo.InvariantCulture)}&";
}
-#pragma warning restore CS0612
+#pragma warning restore CS0618
}
else
{
@@ -1047,6 +1047,7 @@ public enum Currency
}
+#pragma warning disable CA1707 // Underscore in identifier
///
/// Operation modes of the BezahlCode
///
@@ -1055,7 +1056,7 @@ public enum AuthorityType
///
/// Single payment (Überweisung)
///
- [Obsolete]
+ [Obsolete("Use singlepaymentsepa instead for SEPA-compliant payments")]
singlepayment,
///
/// Single SEPA payment (SEPA-Überweisung)
@@ -1064,7 +1065,7 @@ public enum AuthorityType
///
/// Single debit (Lastschrift)
///
- [Obsolete]
+ [Obsolete("Use singledirectdebitsepa instead for SEPA-compliant payments")]
singledirectdebit,
///
/// Single SEPA debit (SEPA-Lastschrift)
@@ -1073,7 +1074,7 @@ public enum AuthorityType
///
/// Periodic payment (Dauerauftrag)
///
- [Obsolete]
+ [Obsolete("Use periodicsinglepaymentsepa instead for SEPA-compliant payments")]
periodicsinglepayment,
///
/// Periodic SEPA payment (SEPA-Dauerauftrag)
@@ -1088,6 +1089,7 @@ public enum AuthorityType
///
contact_v2
}
+#pragma warning restore CA1707 // Underscore in identifier
///
/// Exception class for BezahlCode errors.
diff --git a/QRCoder/PayloadGenerator/BitcoinLikeCryptoCurrencyAddress.cs b/QRCoder/PayloadGenerator/BitcoinLikeCryptoCurrencyAddress.cs
index f2c5cf3f..d9f05245 100644
--- a/QRCoder/PayloadGenerator/BitcoinLikeCryptoCurrencyAddress.cs
+++ b/QRCoder/PayloadGenerator/BitcoinLikeCryptoCurrencyAddress.cs
@@ -61,7 +61,7 @@ public override string ToString()
.ToArray());
}
- return $"{Enum.GetName(typeof(BitcoinLikeCryptoCurrencyType), _currencyType)!.ToLower()}:{_address}{query}";
+ return $"{Enum.GetName(typeof(BitcoinLikeCryptoCurrencyType), _currencyType)!.ToLowerInvariant()}:{_address}{query}";
}
///
diff --git a/QRCoder/PayloadGenerator/CalendarEvent.cs b/QRCoder/PayloadGenerator/CalendarEvent.cs
index 8a33dfc5..d59321d6 100644
--- a/QRCoder/PayloadGenerator/CalendarEvent.cs
+++ b/QRCoder/PayloadGenerator/CalendarEvent.cs
@@ -50,8 +50,8 @@ public CalendarEvent(string subject, string? description, string? location, Date
if (end.Kind == DateTimeKind.Utc)
dtFormatEnd = "yyyyMMddTHHmmssZ";
}
- _start = start.ToString(dtFormatStart);
- _end = end.ToString(dtFormatEnd);
+ _start = start.ToString(dtFormatStart, CultureInfo.InvariantCulture);
+ _end = end.ToString(dtFormatEnd, CultureInfo.InvariantCulture);
}
///
diff --git a/QRCoder/PayloadGenerator/ContactData.cs b/QRCoder/PayloadGenerator/ContactData.cs
index f31d7e0d..09fefd53 100644
--- a/QRCoder/PayloadGenerator/ContactData.cs
+++ b/QRCoder/PayloadGenerator/ContactData.cs
@@ -136,7 +136,7 @@ public override string ToString()
if (!string.IsNullOrEmpty(_note))
payload += $"NOTE:{_note}\r\n";
if (_birthday != null)
- payload += $"BDAY:{((DateTime)_birthday).ToString("yyyyMMdd")}\r\n";
+ payload += $"BDAY:{((DateTime)_birthday).ToString("yyyyMMdd", CultureInfo.InvariantCulture)}\r\n";
// RFC 2426 Section 3.2.1: ADR format is PO Box; Extended Address; Street; Locality (City); Region; Postal Code; Country
string addressString = string.Empty;
if (_addressOrder == AddressOrder.Default)
@@ -232,7 +232,7 @@ public override string ToString()
payload += addressString;
if (_birthday != null)
- payload += $"BDAY:{((DateTime)_birthday).ToString("yyyyMMdd")}\r\n";
+ payload += $"BDAY:{((DateTime)_birthday).ToString("yyyyMMdd", CultureInfo.InvariantCulture)}\r\n";
if (!string.IsNullOrEmpty(_website))
payload += $"URL:{_website}\r\n";
if (!string.IsNullOrEmpty(_email))
diff --git a/QRCoder/PayloadGenerator/Girocode.cs b/QRCoder/PayloadGenerator/Girocode.cs
index 54c06671..fedd794d 100644
--- a/QRCoder/PayloadGenerator/Girocode.cs
+++ b/QRCoder/PayloadGenerator/Girocode.cs
@@ -42,14 +42,14 @@ public Girocode(string iban, string? bic, string name, decimal amount, string re
_encoding = encoding;
if (!IsValidIban(iban))
throw new GirocodeException("The IBAN entered isn't valid.");
- _iban = iban.Replace(" ", "").ToUpper();
+ _iban = iban.Replace(" ", "").ToUpperInvariant();
if (!IsValidBic(bic, _version == GirocodeVersion.Version1))
throw new GirocodeException("The BIC entered isn't valid.");
- _bic = bic?.Replace(" ", "").ToUpper() ?? string.Empty;
+ _bic = bic?.Replace(" ", "").ToUpperInvariant() ?? string.Empty;
if (name.Length > 70)
throw new GirocodeException("(Payee-)Name must be shorter than 71 chars.");
_name = name;
- if (amount.ToString().Replace(",", ".").Contains(".") && amount.ToString().Replace(",", ".").Split('.')[1].TrimEnd('0').Length > 2)
+ if (amount.ToString(CultureInfo.InvariantCulture).Contains('.') && amount.ToString(CultureInfo.InvariantCulture).Split('.')[1].TrimEnd('0').Length > 2)
throw new GirocodeException("Amount must have less than 3 digits after decimal point.");
if (amount < 0.01m || amount > 999999999.99m)
throw new GirocodeException("Amount has to be at least 0.01 and must be smaller or equal to 999999999.99.");
@@ -81,7 +81,7 @@ public override string ToString()
girocodePayload += _bic + _br;
girocodePayload += _name + _br;
girocodePayload += _iban + _br;
- girocodePayload += $"EUR{_amount:0.00}".Replace(",", ".") + _br;
+ girocodePayload += string.Format(CultureInfo.InvariantCulture, "EUR{0:0.00}", _amount) + _br;
girocodePayload += _purposeOfCreditTransfer + _br;
girocodePayload += ((_typeOfRemittance == TypeOfRemittance.Structured)
? _remittanceInformation
@@ -126,6 +126,7 @@ public enum TypeOfRemittance
Unstructured
}
+#pragma warning disable CA1707 // Underscore in identifier
///
/// Defines the encoding types for Girocode payloads.
///
@@ -171,6 +172,7 @@ public enum GirocodeEncoding
///
ISO_8859_15
}
+#pragma warning restore CA1707 // Underscore in identifier
///
/// Represents errors that occur during Girocode generation.
diff --git a/QRCoder/PayloadGenerator/MoneroTransaction.cs b/QRCoder/PayloadGenerator/MoneroTransaction.cs
index 7628d08c..1ff7292b 100644
--- a/QRCoder/PayloadGenerator/MoneroTransaction.cs
+++ b/QRCoder/PayloadGenerator/MoneroTransaction.cs
@@ -42,7 +42,7 @@ public override string ToString()
var moneroUri = $"monero://{_address}{(!string.IsNullOrEmpty(_txPaymentId) || !string.IsNullOrEmpty(_recipientName) || !string.IsNullOrEmpty(_txDescription) || _txAmount != null ? "?" : string.Empty)}";
moneroUri += (!string.IsNullOrEmpty(_txPaymentId) ? $"tx_payment_id={Uri.EscapeDataString(_txPaymentId)}&" : string.Empty);
moneroUri += (!string.IsNullOrEmpty(_recipientName) ? $"recipient_name={Uri.EscapeDataString(_recipientName)}&" : string.Empty);
- moneroUri += (_txAmount != null ? $"tx_amount={_txAmount.ToString()!.Replace(",", ".")}&" : string.Empty);
+ moneroUri += (_txAmount != null ? $"tx_amount={_txAmount.Value.ToString(CultureInfo.InvariantCulture)}&" : string.Empty);
moneroUri += (!string.IsNullOrEmpty(_txDescription) ? $"tx_description={Uri.EscapeDataString(_txDescription)}" : string.Empty);
return moneroUri.TrimEnd('&');
}
diff --git a/QRCoder/PayloadGenerator/OneTimePassword.cs b/QRCoder/PayloadGenerator/OneTimePassword.cs
index 36bf6a02..e81eeb87 100644
--- a/QRCoder/PayloadGenerator/OneTimePassword.cs
+++ b/QRCoder/PayloadGenerator/OneTimePassword.cs
@@ -52,7 +52,7 @@ public OoneTimePasswordAuthAlgorithm Algorithm
///
/// The counter value for HOTP (only used if Type is HOTP).
///
- public int? Counter { get; set; } = null;
+ public int? Counter { get; set; }
///
/// The period in seconds for TOTP (default is 30).
@@ -153,7 +153,7 @@ private string TimeToString()
{
if (Period == null)
{
- throw new Exception("Period must be set when using OneTimePasswordAuthType.TOTP");
+ throw new InvalidOperationException("Period must be set when using OneTimePasswordAuthType.TOTP");
}
var sb = new StringBuilder("otpauth://totp/");
@@ -176,7 +176,7 @@ private void ProcessCommonFields(StringBuilder sb)
{
if (Secret.IsNullOrWhiteSpace())
{
- throw new Exception("Secret must be a filled out base32 encoded string");
+ throw new InvalidOperationException("Secret must be a filled out base32 encoded string");
}
string strippedSecret = Secret.Replace(" ", "");
string? escapedIssuer = null;
@@ -185,18 +185,18 @@ private void ProcessCommonFields(StringBuilder sb)
if (!Issuer.IsNullOrWhiteSpace())
{
- if (Issuer.Contains(":"))
+ if (Issuer.Contains(':'))
{
- throw new Exception("Issuer must not have a ':'");
+ throw new InvalidOperationException("Issuer must not have a ':'");
}
escapedIssuer = Uri.EscapeDataString(Issuer);
}
if (!Label.IsNullOrWhiteSpace())
{
- if (Label.Contains(":"))
+ if (Label.Contains(':'))
{
- throw new Exception("Label must not have a ':'");
+ throw new InvalidOperationException("Label must not have a ':'");
}
escapedLabel = Uri.EscapeDataString(Label);
}
diff --git a/QRCoder/PayloadGenerator/RussiaPaymentOrder.cs b/QRCoder/PayloadGenerator/RussiaPaymentOrder.cs
index f31f4410..1ecd7194 100644
--- a/QRCoder/PayloadGenerator/RussiaPaymentOrder.cs
+++ b/QRCoder/PayloadGenerator/RussiaPaymentOrder.cs
@@ -90,7 +90,7 @@ public byte[] ToBytes()
_separator = DetermineSeparator();
//Create the payload string
- string ret = $"ST0001" + ((int)_characterSet).ToString() + //(separator != "|" ? separator : "") +
+ string ret = $"ST0001" + ((int)_characterSet).ToString(CultureInfo.InvariantCulture) + //(separator != "|" ? separator : "") +
$"{_separator}Name={_mFields.Name}" +
$"{_separator}PersonalAcc={_mFields.PersonalAcc}" +
$"{_separator}BankName={_mFields.BankName}" +
@@ -156,7 +156,7 @@ private List GetOptionalFieldsAsList()
.Select(field =>
{
var objValue = field.GetValue(_oFields, null);
- var value = field.PropertyType.Equals(typeof(DateTime?)) ? ((DateTime)objValue!).ToString("dd.MM.yyyy") : objValue!.ToString();
+ var value = field.PropertyType.Equals(typeof(DateTime?)) ? ((DateTime)objValue!).ToString("dd.MM.yyyy", CultureInfo.InvariantCulture) : objValue!.ToString();
return $"{field.Name}={value}";
})
.ToList();
@@ -186,7 +186,7 @@ private List GetMandatoryFieldsAsList()
.Select(field =>
{
var objValue = field.GetValue(_mFields);
- var value = field.FieldType.Equals(typeof(DateTime?)) ? ((DateTime)objValue!).ToString("dd.MM.yyyy") : objValue!.ToString();
+ var value = field.FieldType.Equals(typeof(DateTime?)) ? ((DateTime)objValue!).ToString("dd.MM.yyyy", CultureInfo.InvariantCulture) : objValue!.ToString();
return $"{field.Name}={value}";
})
.ToList();
@@ -575,6 +575,7 @@ public string? TaxPaytKind
public TechCode? TechCode { get; set; }
}
+#pragma warning disable CA1707 // Underscore in identifier
///
/// (List of values of the technical code of the payment)
/// Перечень значений технического кода платежа
@@ -692,6 +693,7 @@ public enum CharacterSets
///
koi8_r = 3
}
+#pragma warning restore CA1707 // Underscore in identifier
///
/// Represents errors that occur during the generation of a RussiaPaymentOrder payload.
diff --git a/QRCoder/PayloadGenerator/SMS.cs b/QRCoder/PayloadGenerator/SMS.cs
index 6d167c22..935ab35f 100644
--- a/QRCoder/PayloadGenerator/SMS.cs
+++ b/QRCoder/PayloadGenerator/SMS.cs
@@ -47,6 +47,7 @@ public SMS(string number, string subject, SMSEncoding encoding = SMSEncoding.SMS
_ => string.Empty,
};
+#pragma warning disable CA1707 // Underscore in identifier
///
/// Specifies the encoding type for the SMS payload.
///
@@ -65,5 +66,6 @@ public enum SMSEncoding
///
SMS_iOS
}
+#pragma warning restore CA1707 // Underscore in identifier
}
}
diff --git a/QRCoder/PayloadGenerator/SlovenianUpnQr.cs b/QRCoder/PayloadGenerator/SlovenianUpnQr.cs
index cdf4776b..8a7f9fb5 100644
--- a/QRCoder/PayloadGenerator/SlovenianUpnQr.cs
+++ b/QRCoder/PayloadGenerator/SlovenianUpnQr.cs
@@ -45,7 +45,7 @@ public class SlovenianUpnQr : Payload
/// The string to limit.
/// The maximum length of the string.
/// The limited string.
- private string LimitLength(string value, int maxLength)
+ private static string LimitLength(string value, int maxLength)
=> (value.Length <= maxLength) ? value : value.Substring(0, maxLength);
///
@@ -89,14 +89,14 @@ public SlovenianUpnQr(string payerName, string payerAddress, string payerPlace,
_payerAddress = LimitLength(payerAddress.Trim(), 33);
_payerPlace = LimitLength(payerPlace.Trim(), 33);
_amount = FormatAmount(amount);
- _code = LimitLength(code.Trim().ToUpper(), 4);
+ _code = LimitLength(code.Trim().ToUpperInvariant(), 4);
_purpose = LimitLength(description.Trim(), 42);
- _deadLine = (deadline == null) ? "" : deadline.Value.ToString("dd.MM.yyyy");
+ _deadLine = (deadline == null) ? "" : deadline.Value.ToString("dd.MM.yyyy", CultureInfo.InvariantCulture);
_recipientIban = LimitLength(recipientIban.Trim(), 34);
_recipientName = LimitLength(recipientName.Trim(), 33);
_recipientAddress = LimitLength(recipientAddress.Trim(), 33);
_recipientPlace = LimitLength(recipientPlace.Trim(), 33);
- _recipientSiModel = LimitLength(recipientSiModel.Trim().ToUpper(), 4);
+ _recipientSiModel = LimitLength(recipientSiModel.Trim().ToUpperInvariant(), 4);
_recipientSiReference = LimitLength(recipientSiReference.Trim(), 22);
}
@@ -106,10 +106,10 @@ public SlovenianUpnQr(string payerName, string payerAddress, string payerPlace,
///
/// The amount to format.
/// The formatted amount string.
- private string FormatAmount(double amount)
+ private static string FormatAmount(double amount)
{
int _amt = (int)Math.Round(amount * 100.0);
- return string.Format("{0:00000000000}", _amt);
+ return string.Format(CultureInfo.InvariantCulture, "{0:00000000000}", _amt);
}
///
@@ -148,15 +148,15 @@ public override string ToString()
_sb.Append(_payerAddress).Append('\n');
_sb.Append(_payerPlace).Append('\n');
_sb.Append(_amount).Append('\n').Append('\n').Append('\n');
- _sb.Append(_code.ToUpper()).Append('\n');
+ _sb.Append(_code.ToUpperInvariant()).Append('\n');
_sb.Append(_purpose).Append('\n');
_sb.Append(_deadLine).Append('\n');
- _sb.Append(_recipientIban.ToUpper()).Append('\n');
+ _sb.Append(_recipientIban.ToUpperInvariant()).Append('\n');
_sb.Append(_recipientSiModel).Append(_recipientSiReference).Append('\n');
_sb.Append(_recipientName).Append('\n');
_sb.Append(_recipientAddress).Append('\n');
_sb.Append(_recipientPlace).Append('\n');
- _sb.AppendFormat("{0:000}", CalculateChecksum()).Append('\n');
+ _sb.AppendFormat(CultureInfo.InvariantCulture, "{0:000}", CalculateChecksum()).Append('\n');
return _sb.ToString();
}
}
diff --git a/QRCoder/PayloadGenerator/SwissQrCode.cs b/QRCoder/PayloadGenerator/SwissQrCode.cs
index ea1ed9fe..57384154 100644
--- a/QRCoder/PayloadGenerator/SwissQrCode.cs
+++ b/QRCoder/PayloadGenerator/SwissQrCode.cs
@@ -52,7 +52,7 @@ public SwissQrCode(Iban iban, Currency currency, Contact creditor, Reference ref
_additionalInformation = additionalInformation ?? new AdditionalInformation();
- if (amount != null && amount.ToString()!.Length > 12)
+ if (amount != null && amount.Value.ToString(CultureInfo.InvariantCulture).Length > 12)
throw new SwissQrCodeException("Amount (including decimals) must be shorter than 13 places.");
_amount = amount;
@@ -275,7 +275,7 @@ public Iban(string iban, IbanType ibanType)
throw new SwissQrCodeIbanException("The IBAN entered isn't valid.");
if (ibanType == IbanType.QrIban && !IsValidQRIban(iban))
throw new SwissQrCodeIbanException("The QR-IBAN entered isn't valid.");
- if (!iban.StartsWith("CH") && !iban.StartsWith("LI"))
+ if (!iban.StartsWith("CH", StringComparison.Ordinal) && !iban.StartsWith("LI", StringComparison.Ordinal))
throw new SwissQrCodeIbanException("The IBAN must start with \"CH\" or \"LI\".");
_iban = iban;
_ibanType = ibanType;
@@ -591,7 +591,7 @@ public override string ToString()
SwissQrCodePayload += _alternativeProcedure2!.Replace("\n", "") + _br; //AltPmt
//S-QR specification 2.0, chapter 4.2.3
- if (SwissQrCodePayload.EndsWith(_br))
+ if (SwissQrCodePayload.EndsWith(_br, StringComparison.Ordinal))
SwissQrCodePayload = SwissQrCodePayload.Remove(SwissQrCodePayload.Length - _br.Length);
return SwissQrCodePayload;
diff --git a/QRCoder/PdfByteQRCode.cs b/QRCoder/PdfByteQRCode.cs
index 5b90a707..d534051e 100644
--- a/QRCoder/PdfByteQRCode.cs
+++ b/QRCoder/PdfByteQRCode.cs
@@ -31,21 +31,6 @@ public PdfByteQRCode(QRCodeData data) : base(data) { }
public byte[] GetGraphic(int pixelsPerModule)
=> GetGraphic(pixelsPerModule, "#000000", "#ffffff");
- ///
- /// Converts a hexadecimal color string to a byte array.
- ///
- /// Color in HEX format like #ffffff.
- /// Returns the color as a byte array.
- private byte[] HexColorToByteArray(string colorString)
- {
- if (colorString.StartsWith("#"))
- colorString = colorString.Substring(1);
- byte[] byteColor = new byte[colorString.Length / 2];
- for (int i = 0; i < byteColor.Length; i++)
- byteColor[i] = byte.Parse(colorString.Substring(i * 2, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture);
- return byteColor;
- }
-
///
/// Creates a PDF document with specified colors and DPI.
///
@@ -63,8 +48,8 @@ public byte[] GetGraphic(int pixelsPerModule, string darkColorHtmlHex, string li
var pdfMediaSize = ToStr(imgSize * 72 / (float)dpi);
// Parse colors
- var darkColor = HexColorToByteArray(darkColorHtmlHex);
- var lightColor = HexColorToByteArray(lightColorHtmlHex);
+ var darkColor = darkColorHtmlHex.HexColorToByteArray();
+ var lightColor = lightColorHtmlHex.HexColorToByteArray();
var darkColorPdf = ColorToPdfRgb(darkColor);
var lightColorPdf = ColorToPdfRgb(lightColor);
diff --git a/QRCoder/PostscriptQRCode.cs b/QRCoder/PostscriptQRCode.cs
index e57a4204..c3064644 100644
--- a/QRCoder/PostscriptQRCode.cs
+++ b/QRCoder/PostscriptQRCode.cs
@@ -100,11 +100,11 @@ public string GetGraphic(Size viewBox, Color darkColor, Color lightColor, bool d
var drawableModulesCount = QrCodeData.ModuleMatrix.Count - (drawQuietZones ? 0 : offset * 2);
var pointsPerModule = (double)Math.Min(viewBox.Width, viewBox.Height) / (double)drawableModulesCount;
- string psFile = string.Format(PS_HEADER, new object[] {
+ string psFile = string.Format(CultureInfo.InvariantCulture, PS_HEADER, new object[] {
CleanSvgVal(viewBox.Width), CleanSvgVal(pointsPerModule),
epsFormat ? "EPSF-3.0" : string.Empty
});
- psFile += string.Format(PS_FUNCTIONS, new object[] {
+ psFile += string.Format(CultureInfo.InvariantCulture, PS_FUNCTIONS, new object[] {
CleanSvgVal(darkColor.R /255.0), CleanSvgVal(darkColor.G /255.0), CleanSvgVal(darkColor.B /255.0),
CleanSvgVal(lightColor.R /255.0), CleanSvgVal(lightColor.G /255.0), CleanSvgVal(lightColor.B /255.0),
drawableModulesCount
@@ -128,7 +128,7 @@ public string GetGraphic(Size viewBox, Color darkColor, Color lightColor, bool d
///
/// The input double value.
/// Returns the cleaned string representation of the double value.
- private string CleanSvgVal(double input) => input.ToString(System.Globalization.CultureInfo.InvariantCulture);
+ private static string CleanSvgVal(double input) => input.ToString(System.Globalization.CultureInfo.InvariantCulture);
// Note: line terminations here will encode differently based on which platform QRCoder was compiled on (CRLF vs LF);
// however, PostScript interpreters should handle both equally well.
diff --git a/QRCoder/QRCode.cs b/QRCoder/QRCode.cs
index 44705511..ceb02fdd 100644
--- a/QRCoder/QRCode.cs
+++ b/QRCoder/QRCode.cs
@@ -152,7 +152,7 @@ public Bitmap GetGraphic(int pixelsPerModule, Color darkColor, Color lightColor,
/// The rectangle for which to create the rounded path.
/// The radius of the corners.
/// Returns the rounded rectangle path.
- internal GraphicsPath CreateRoundedRectanglePath(RectangleF rect, int cornerRadius)
+ internal static GraphicsPath CreateRoundedRectanglePath(RectangleF rect, int cornerRadius)
{
var roundedRect = new GraphicsPath();
roundedRect.AddArc(rect.X, rect.Y, cornerRadius * 2, cornerRadius * 2, 180, 90);
diff --git a/QRCoder/QRCodeData.cs b/QRCoder/QRCodeData.cs
index d1d3611f..b8d56643 100644
--- a/QRCoder/QRCodeData.cs
+++ b/QRCoder/QRCodeData.cs
@@ -78,23 +78,23 @@ public QRCodeData(byte[] rawData, Compression compressMode)
}
if (rawData.Length < 5)
- throw new Exception("Invalid raw data file. File too short.");
+ throw new InvalidDataException("Invalid raw data file. File too short.");
if (rawData[0] != 0x51 || rawData[1] != 0x52 || rawData[2] != 0x52)
- throw new Exception("Invalid raw data file. Filetype doesn't match \"QRR\".");
+ throw new InvalidDataException("Invalid raw data file. Filetype doesn't match \"QRR\".");
// Set QR code version from side length (includes 8-module quiet zone)
var sideLen = (int)rawData[4];
if (sideLen < 29) // Micro QR: sideLen = 19 + 2*(m-1), m in [1..4] -> versions -1..-4
{
if (((sideLen - 19) & 1) != 0)
- throw new Exception("Invalid raw data file. Side length not valid for Micro QR.");
+ throw new InvalidDataException("Invalid raw data file. Side length not valid for Micro QR.");
var m = ((sideLen - 19) / 2) + 1;
Version = -m;
}
else // Standard QR: sideLen = 29 + 4*(v-1), v in [1..40]
{
if (((sideLen - 29) % 4) != 0)
- throw new Exception("Invalid raw data file. Side length not valid for QR.");
+ throw new InvalidDataException("Invalid raw data file. Side length not valid for QR.");
Version = ((sideLen - 29) / 4) + 1;
}
@@ -219,11 +219,11 @@ private static int ModulesPerSideFromVersion(int version)
///
/// Releases all resources used by the .
///
- public void Dispose()
+ public virtual void Dispose()
{
ModuleMatrix = null!;
Version = 0;
-
+ GC.SuppressFinalize(this);
}
///
diff --git a/QRCoder/QRCodeGenerator.cs b/QRCoder/QRCodeGenerator.cs
index 020d7302..4970f1aa 100644
--- a/QRCoder/QRCodeGenerator.cs
+++ b/QRCoder/QRCodeGenerator.cs
@@ -24,7 +24,9 @@ public QRCodeGenerator()
/// A payload object, generated by the PayloadGenerator-class
/// Thrown when the payload is too big to be encoded in a QR code.
/// Returns the raw QR code data which can be used for rendering.
+#pragma warning disable CA1822 // Mark members as static
public QRCodeData CreateQrCode(PayloadGenerator.Payload payload)
+#pragma warning restore CA1822 // Mark members as static
=> GenerateQrCode(payload);
///
@@ -34,7 +36,9 @@ public QRCodeData CreateQrCode(PayloadGenerator.Payload payload)
/// The level of error correction data
/// Thrown when the payload is too big to be encoded in a QR code.
/// Returns the raw QR code data which can be used for rendering.
+#pragma warning disable CA1822 // Mark members as static
public QRCodeData CreateQrCode(PayloadGenerator.Payload payload, ECCLevel eccLevel)
+#pragma warning restore CA1822 // Mark members as static
=> GenerateQrCode(payload, eccLevel);
///
@@ -48,7 +52,9 @@ public QRCodeData CreateQrCode(PayloadGenerator.Payload payload, ECCLevel eccLev
/// Set fixed QR code target version.
/// Thrown when the payload is too big to be encoded in a QR code.
/// Returns the raw QR code data which can be used for rendering.
+#pragma warning disable CA1822 // Mark members as static
public QRCodeData CreateQrCode(string plainText, ECCLevel eccLevel, bool forceUtf8 = false, bool utf8BOM = false, EciMode eciMode = EciMode.Default, int requestedVersion = -1)
+#pragma warning restore CA1822 // Mark members as static
=> GenerateQrCode(plainText, eccLevel, forceUtf8, utf8BOM, eciMode, requestedVersion);
///
@@ -58,7 +64,9 @@ public QRCodeData CreateQrCode(string plainText, ECCLevel eccLevel, bool forceUt
/// The level of error correction data
/// Thrown when the payload is too big to be encoded in a QR code.
/// Returns the raw QR code data which can be used for rendering.
+#pragma warning disable CA1822 // Mark members as static
public QRCodeData CreateQrCode(byte[] binaryData, ECCLevel eccLevel)
+#pragma warning restore CA1822 // Mark members as static
=> GenerateQrCode(binaryData, eccLevel);
@@ -192,7 +200,7 @@ public static QRCodeData GenerateMicroQrCode(string plainText, ECCLevel eccLevel
.First(x => (x.ErrorCorrectionLevel == eccLevel || (eccLevel == ECCLevel.Default && x.ErrorCorrectionLevel == ECCLevel.L)))
.CapacityDict.TryGetValue(encoding, out var maxSizeByte);
if (!matchedEncoding)
- throw new ArgumentOutOfRangeException(nameof(encoding), encoding, "Encoding not supported for this version.");
+ throw new InvalidOperationException("Required encoding is not supported for this version.");
throw new QRCoder.Exceptions.DataTooLongException(eccLevel.ToString(), encoding.ToString(), version, maxSizeByte);
}
}
@@ -1368,8 +1376,9 @@ static int[] GetNotUniqueExponents(Polynom list)
}
///
- public void Dispose()
+ public virtual void Dispose()
{
// left for back-compat
+ GC.SuppressFinalize(this);
}
}
diff --git a/QRCoder/QRCodeGenerator/EciMode.cs b/QRCoder/QRCodeGenerator/EciMode.cs
index 4cf253be..d73fd27a 100644
--- a/QRCoder/QRCodeGenerator/EciMode.cs
+++ b/QRCoder/QRCodeGenerator/EciMode.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CA1707 // Underscore in identifier
+
namespace QRCoder;
public partial class QRCodeGenerator
diff --git a/QRCoder/QRCodeGenerator/Point.cs b/QRCoder/QRCodeGenerator/Point.cs
index 36255b46..6ec9d532 100644
--- a/QRCoder/QRCodeGenerator/Point.cs
+++ b/QRCoder/QRCodeGenerator/Point.cs
@@ -41,5 +41,16 @@ public Point(int x, int y)
///
public bool Equals(Point other)
=> X == other.X && Y == other.Y;
+
+ ///
+ public override bool Equals(object? obj) => obj is Point point && Equals(point);
+
+ ///
+ public override int GetHashCode()
+#if NET5_0_OR_GREATER
+ => HashCode.Combine(X, Y);
+#else
+ => X ^ (int)(((uint)Y << 16) | ((uint)Y >> 16));
+#endif
}
}
diff --git a/QRCoder/QRCodeGenerator/Polynom.cs b/QRCoder/QRCodeGenerator/Polynom.cs
index 1e6e9a57..90237945 100644
--- a/QRCoder/QRCodeGenerator/Polynom.cs
+++ b/QRCoder/QRCodeGenerator/Polynom.cs
@@ -36,7 +36,7 @@ public void Add(PolynomItem item)
public void RemoveAt(int index)
{
if ((uint)index >= (uint)Count)
- throw new IndexOutOfRangeException();
+ ThrowIndexArgumentOutOfRangeException();
if (index < Count - 1)
Array.Copy(_polyItems, index + 1, _polyItems, index, Count - index - 1);
@@ -52,13 +52,13 @@ public PolynomItem this[int index]
get
{
if ((uint)index >= Count)
- ThrowIndexOutOfRangeException();
+ ThrowIndexArgumentOutOfRangeException();
return _polyItems[index];
}
set
{
if ((uint)index >= Count)
- ThrowIndexOutOfRangeException();
+ ThrowIndexArgumentOutOfRangeException();
_polyItems[index] = value;
}
}
@@ -66,7 +66,7 @@ public PolynomItem this[int index]
#if NET6_0_OR_GREATER
[StackTraceHidden]
#endif
- private static void ThrowIndexOutOfRangeException() => throw new IndexOutOfRangeException();
+ private static void ThrowIndexArgumentOutOfRangeException() => throw new ArgumentOutOfRangeException("index");
///
diff --git a/QRCoder/SvgQRCode.cs b/QRCoder/SvgQRCode.cs
index 7b34be0f..1079baae 100644
--- a/QRCoder/SvgQRCode.cs
+++ b/QRCoder/SvgQRCode.cs
@@ -152,7 +152,9 @@ public string GetGraphic(Size viewBox, string darkColorHex, string lightColorHex
}
var svgFile = new StringBuilder($@"