Skip to content

Commit

Permalink
Improve Code Quality 3 (#805)
Browse files Browse the repository at this point in the history
* Throw when trying to inverse a matrix with a determinant of 0

* Optimize Hex.GetString on .NET

* Updates tests for Matrix3x3.Inverse() change

* Eliminate allocation in InternalStringExtensions

* Use vectorized Span.Fill method

* Eliminate various string allocations when parsing numbers

* Remove unused using statements

* Fix Matrix3x3 Equals nullability
  • Loading branch information
iamcarbon authored Mar 17, 2024
1 parent a412a23 commit 69e2b7b
Show file tree
Hide file tree
Showing 12 changed files with 55 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@ public class InternalStringExtensionsTests
[InlineData("pineapple", "apple", 4, true)]
public void StartsWithOffset(string input, string start, int offset, bool expected)
{
var result = input.StartsWithOffset(start, offset);
var result = input.StartsWithOffset(start.AsSpan(), offset);

Assert.Equal(expected, result);
}

[Fact]
public void StartsWithOffset_NegativeOffset_Throws()
{
Action action = () => "any".StartsWithOffset("x", -1);
Action action = () => "any".StartsWithOffset("x".AsSpan(), -1);

Assert.Throws<ArgumentOutOfRangeException>(action);
}
}
}
}
5 changes: 2 additions & 3 deletions src/UglyToad.PdfPig.Tests/Util/Matrix3x3Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,15 +106,14 @@ public void InverseReturnsMatrixIfPossible()
}

[Fact]
public void InverseReturnsNullIfNotPossible()
public void InverseThrowsNotPossible()
{
var matrix = new Matrix3x3(
1, 2, 3,
4, 5, 6,
7, 8, 9);

var inverse = matrix.Inverse();
Assert.Null(inverse);
Assert.Throws<InvalidOperationException>(() => matrix.Inverse());
}
}
}
5 changes: 2 additions & 3 deletions src/UglyToad.PdfPig/Filters/CcittFaxDecoderStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using System;
using System.IO;
using IO;
using Util;

/// <summary>
/// CCITT Modified Huffman RLE, Group 3 (T4) and Group 4 (T6) fax compression.
Expand Down Expand Up @@ -426,7 +425,7 @@ public override int Read(byte[] b, int off, int len)
{
if (decodedLength < 0)
{
ArrayHelper.Fill(b, off, off + len, (byte)0x0);
b.AsSpan(off, len).Fill(0x0);
return len;
}

Expand All @@ -436,7 +435,7 @@ public override int Read(byte[] b, int off, int len)

if (decodedLength < 0)
{
ArrayHelper.Fill(b, off, off + len, (byte)0x0);
b.AsSpan(off, len).Fill(0x0);
return len;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/UglyToad.PdfPig/Graphics/Colors/ChromaticAdaptation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public ChromaticAdaptation(
Method method = Method.Bradford)
{
var coneReponseDomain = GetConeResponseDomain(method)!;
var inverseConeResponseDomain = coneReponseDomain.Inverse()!;
var inverseConeResponseDomain = coneReponseDomain.Inverse();
var (ρS, γS, βS) = coneReponseDomain.Multiply(sourceReferenceWhite);

var (ρD, γD, βD) = coneReponseDomain.Multiply(destinationReferenceWhite);
Expand Down
5 changes: 3 additions & 2 deletions src/UglyToad.PdfPig/Parser/FileStructure/FileHeaderParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Logging;
using Tokenization.Scanner;
using Tokens;
using UglyToad.PdfPig.Util;

/// <summary>
/// Used to retrieve the version header from the PDF file.
Expand Down Expand Up @@ -70,7 +71,7 @@ private static HeaderVersion GetHeaderVersionAndResetScanner(CommentToken commen

const int toDoubleStartLength = 4;

if (!double.TryParse(comment.Data.Substring(toDoubleStartLength),
if (!double.TryParse(comment.Data.AsSpanOrSubstring(toDoubleStartLength),
NumberStyles.Number,
CultureInfo.InvariantCulture,
out var version))
Expand Down Expand Up @@ -118,7 +119,7 @@ private static bool TryBruteForceVersionLocation(long startPosition, IInputBytes

if (actualIndex >= 0 && content.Length - actualIndex >= versionLength)
{
var numberPart = content.Substring(actualIndex + 5, 3);
var numberPart = content.AsSpanOrSubstring(actualIndex + 5, 3);
if (double.TryParse(
numberPart,
NumberStyles.Number,
Expand Down
30 changes: 0 additions & 30 deletions src/UglyToad.PdfPig/Util/ArrayHelper.cs

This file was deleted.

17 changes: 9 additions & 8 deletions src/UglyToad.PdfPig/Util/DateFormatHelper.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
namespace UglyToad.PdfPig.Util
{
using System;
using System.Globalization;

/// <summary>
/// Helper class for dates.
Expand Down Expand Up @@ -53,7 +54,7 @@ bool IsWithinRange(int val, int min, int max)
return false;
}

if (!int.TryParse(s.Substring(location, 4), out var year))
if (!int.TryParse(s.AsSpanOrSubstring(location, 4), NumberStyles.Integer, CultureInfo.InvariantCulture, out var year))
{
return false;
}
Expand All @@ -72,7 +73,7 @@ bool IsWithinRange(int val, int min, int max)
return true;
}

if (!int.TryParse(s.Substring(location, 2), out var month)
if (!int.TryParse(s.AsSpanOrSubstring(location, 2), NumberStyles.Integer, CultureInfo.InvariantCulture, out var month)
|| !IsWithinRange(month, 1, 12))
{
return false;
Expand All @@ -92,7 +93,7 @@ bool IsWithinRange(int val, int min, int max)
return true;
}

if (!int.TryParse(s.Substring(location, 2), out var day)
if (!int.TryParse(s.AsSpanOrSubstring(location, 2), NumberStyles.Integer, CultureInfo.InvariantCulture, out var day)
|| !IsWithinRange(day, 1, 31))
{
return false;
Expand All @@ -112,7 +113,7 @@ bool IsWithinRange(int val, int min, int max)
return true;
}

if (!int.TryParse(s.Substring(location, 2), out var hour)
if (!int.TryParse(s.AsSpanOrSubstring(location, 2), NumberStyles.Integer, CultureInfo.InvariantCulture, out var hour)
|| !IsWithinRange(hour, 0, 23))
{
return false;
Expand All @@ -132,7 +133,7 @@ bool IsWithinRange(int val, int min, int max)
return true;
}

if (!int.TryParse(s.Substring(location, 2), out var minute)
if (!int.TryParse(s.AsSpanOrSubstring(location, 2), NumberStyles.Integer, CultureInfo.InvariantCulture, out var minute)
|| !IsWithinRange(minute, 0, 59))
{
return false;
Expand All @@ -152,7 +153,7 @@ bool IsWithinRange(int val, int min, int max)
return true;
}

if (!int.TryParse(s.Substring(location, 2), out var second)
if (!int.TryParse(s.AsSpanOrSubstring(location, 2), NumberStyles.Integer, CultureInfo.InvariantCulture, out var second)
|| !IsWithinRange(second, 0, 59))
{
return false;
Expand Down Expand Up @@ -189,7 +190,7 @@ bool IsWithinRange(int val, int min, int max)
return true;
}

if (!HasRemainingCharacters(location, 3) || !int.TryParse(s.Substring(location, 2), out var hoursOffset)
if (!HasRemainingCharacters(location, 3) || !int.TryParse(s.AsSpanOrSubstring(location, 2), NumberStyles.Integer, CultureInfo.InvariantCulture, out var hoursOffset)
|| s[location + 2] != '\''
|| !IsWithinRange(hoursOffset, 0, 23))
{
Expand All @@ -205,7 +206,7 @@ bool IsWithinRange(int val, int min, int max)
return true;
}

if (!HasRemainingCharacters(location, 3) || !int.TryParse(s.Substring(location, 2), out var minutesOffset)
if (!HasRemainingCharacters(location, 3) || !int.TryParse(s.AsSpanOrSubstring(location, 2), NumberStyles.Integer, CultureInfo.InvariantCulture, out var minutesOffset)
|| s[location + 2] != '\''
|| !IsWithinRange(minutesOffset, 0, 59))
{
Expand Down
4 changes: 4 additions & 0 deletions src/UglyToad.PdfPig/Util/Hex.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ internal static class Hex
/// </summary>
public static string GetString(ReadOnlySpan<byte> bytes)
{
#if NET6_0_OR_GREATER
return Convert.ToHexString(bytes);
#else
var stringBuilder = new StringBuilder(bytes.Length * 2);

foreach (var b in bytes)
Expand All @@ -31,6 +34,7 @@ public static string GetString(ReadOnlySpan<byte> bytes)
}

return stringBuilder.ToString();
#endif
}

private static int GetHighNibble(byte b)
Expand Down
28 changes: 25 additions & 3 deletions src/UglyToad.PdfPig/Util/InternalStringExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

internal static class InternalStringExtensions
{
public static bool StartsWithOffset(this string value, string start, int offset)
public static bool StartsWithOffset(this string value, ReadOnlySpan<char> start, int offset)
{
if (offset < 0)
{
Expand All @@ -13,7 +13,7 @@ public static bool StartsWithOffset(this string value, string start, int offset)

if (value is null)
{
if (start is null && offset == 0)
if (start.Length is 0 && offset == 0)
{
return true;
}
Expand All @@ -26,7 +26,29 @@ public static bool StartsWithOffset(this string value, string start, int offset)
return false;
}

return value.Substring(offset).StartsWith(start);
return value.AsSpan(offset).StartsWith(start, StringComparison.Ordinal);
}

#if NET
public static ReadOnlySpan<char> AsSpanOrSubstring(this string text, int start)
{
return text.AsSpan(start);
}

public static ReadOnlySpan<char> AsSpanOrSubstring(this string text, int start, int length)
{
return text.AsSpan(start, length);
}
#else
public static string AsSpanOrSubstring(this string text, int start)
{
return text.Substring(start);
}

public static string AsSpanOrSubstring(this string text, int start, int length)
{
return text.Substring(start, length);
}
#endif
}
}
8 changes: 4 additions & 4 deletions src/UglyToad.PdfPig/Util/Matrix3x3.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace UglyToad.PdfPig.Util
{
internal class Matrix3x3 : IEnumerable<double>, IEquatable<Matrix3x3>
internal sealed class Matrix3x3 : IEnumerable<double>, IEquatable<Matrix3x3>
{
/// <summary>
/// The identity matrix. The result of multiplying a matrix with
Expand Down Expand Up @@ -69,14 +69,14 @@ public IEnumerator<double> GetEnumerator()
///
/// If an inverse matrix does not exist, null is returned.
/// </summary>
public Matrix3x3? Inverse()
public Matrix3x3 Inverse()
{
var determinant = GetDeterminant();

// No inverse matrix exists when determinant is zero
if (determinant == 0)
{
return null;
throw new InvalidOperationException("May not inverse a matrix with a determinant of 0.");
}

var transposed = Transpose();
Expand Down Expand Up @@ -162,7 +162,7 @@ public override bool Equals(object? obj)
public bool Equals(Matrix3x3? other)
{
if (other is null)
{
{
return false;
}

Expand Down
3 changes: 1 addition & 2 deletions src/UglyToad.PdfPig/Writer/PdfA1ARuleBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using UglyToad.PdfPig.Tokens;

namespace UglyToad.PdfPig.Writer
Expand Down
6 changes: 1 addition & 5 deletions src/UglyToad.PdfPig/Writer/PdfWriterType.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
namespace UglyToad.PdfPig.Writer
{
using System;
using System.Collections.Generic;
using System.Text;

/// <summary>
/// Type of pdf writer to use.
/// </summary>
Expand All @@ -18,4 +14,4 @@ public enum PdfWriterType
/// </summary>
ObjectInMemoryDedup
}
}
}

0 comments on commit 69e2b7b

Please sign in to comment.