Improve code quality (#825)

* Avoid encoding ASCII in more cases

* Make Space a const

* Use WriteWhiteSpace extension to eliminate possible virtual call

* Use ASCII when encoding constrained character subset

* Simplify pragmas

* Revert Whitespace rename

* Fix using statement order

* Remove obsolete serialization support on .NET

* Remove obsolete serialization support on .NET (part 2)
This commit is contained in:
Jason Nelson 2024-05-02 23:36:19 -07:00 committed by GitHub
parent 7f42a8d60c
commit da44e1a540
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 152 additions and 148 deletions

View File

@ -1,14 +1,18 @@
namespace UglyToad.PdfPig.Core
{
using System;
#if !NET
using System.Runtime.Serialization;
#endif
/// <inheritdoc />
/// <summary>
/// This exception will be thrown where the contents of the PDF document do not match the specification in such a way that it
/// renders the document unreadable.
/// </summary>
#if !NET
[Serializable]
#endif
public class PdfDocumentFormatException : Exception
{
/// <inheritdoc />
@ -29,11 +33,13 @@
{
}
#if !NET
/// <inheritdoc />
protected PdfDocumentFormatException(
SerializationInfo info,
StreamingContext context) : base(info, context)
{
}
#endif
}
}

View File

@ -1,4 +1,4 @@
#if NETFRAMEWORK || NETSTANDARD2_0
#if !NET
namespace System.Text;

View File

@ -1,4 +1,4 @@
#if NETFRAMEWORK || NETSTANDARD2_0
#if !NET
namespace System.IO;

View File

@ -1,12 +1,16 @@
namespace UglyToad.PdfPig.Fonts
{
using System;
#if !NET
using System.Runtime.Serialization;
#endif
/// <summary>
/// Thrown when a PDF contains an invalid compressed data stream.
/// </summary>
#if !NET
[Serializable]
#endif
public class CorruptCompressedDataException : Exception
{
/// <inheritdoc />
@ -24,11 +28,13 @@
{
}
#if !NET
/// <inheritdoc />
protected CorruptCompressedDataException(
SerializationInfo info,
StreamingContext context) : base(info, context)
{
}
#endif
}
}

View File

@ -1,4 +1,4 @@
#if NETFRAMEWORK || NETSTANDARD2_0
#if !NET
namespace System.Text;

View File

@ -1,4 +1,4 @@
#if NETFRAMEWORK || NETSTANDARD2_0
#if !NET
namespace System.IO;

View File

@ -5,7 +5,7 @@
using Core;
using Tokens;
#if NET8_0_OR_GREATER
#if NET
using System.Text.Unicode;
#endif
@ -13,7 +13,7 @@
{
static NameTokenizer()
{
#if NET6_0_OR_GREATER
#if NET
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
#endif
}

View File

@ -131,7 +131,7 @@
return string.Empty;
}
#if NET6_0_OR_GREATER
#if NET
int length = 0;
for (var i = 0; i < content.Letters.Count; i++)

View File

@ -117,7 +117,7 @@
pageFactoryCache.Add(type, pageFactory);
}
#if NET6_0_OR_GREATER
#if NET
internal void AddPageFactory<TPage, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] TPageFactory>() where TPageFactory : IPageFactory<TPage>
#else
internal void AddPageFactory<TPage, TPageFactory>() where TPageFactory : IPageFactory<TPage>

View File

@ -1,14 +1,18 @@
namespace UglyToad.PdfPig.Exceptions
{
using System;
#if !NET
using System.Runtime.Serialization;
#endif
using Encryption;
/// <inheritdoc />
/// <summary>
/// The document is encrypted and cannot be decrypted.
/// </summary>
#if !NET
[Serializable]
#endif
public class PdfDocumentEncryptedException : Exception
{
internal EncryptionDictionary? Dictionary { get; }
@ -38,11 +42,13 @@
Dictionary = dictionary;
}
#if !NET
/// <inheritdoc />
protected PdfDocumentEncryptedException(
SerializationInfo info,
StreamingContext context) : base(info, context)
{
}
#endif
}
}

View File

@ -576,7 +576,7 @@
}
}
#if NET8_0_OR_GREATER
#if NET
return CollectionsMarshal.AsSpan(transformed);
#else
return transformed.ToArray();
@ -745,7 +745,7 @@
}
}
#if NET8_0_OR_GREATER
#if NET
return CollectionsMarshal.AsSpan(transformed);
#else
return transformed.ToArray();

View File

@ -9,7 +9,7 @@
internal static class OperationWriteHelper
{
private const byte WhiteSpace = (byte)' ';
private const byte Whitespace = (byte)' ';
private const byte NewLine = (byte)'\n';
public static void WriteText(this Stream stream, string text, bool appendWhitespace = false)
@ -36,13 +36,18 @@
#endif
if (appendWhitespace)
{
stream.WriteByte(WhiteSpace);
stream.WriteByte(Whitespace);
}
}
public static void WriteText(this Stream stream, ReadOnlySpan<byte> asciiBytes)
public static void WriteText(this Stream stream, ReadOnlySpan<byte> asciiBytes, bool appendWhitespace = false)
{
stream.Write(asciiBytes);
if (appendWhitespace)
{
stream.WriteByte(Whitespace);
}
}
public static void WriteHex(this Stream stream, ReadOnlySpan<byte> bytes)
@ -60,7 +65,7 @@
public static void WriteWhiteSpace(this Stream stream)
{
stream.WriteByte(WhiteSpace);
stream.WriteByte(Whitespace);
}
public static void WriteNewLine(this Stream stream)
@ -80,7 +85,7 @@
public static void WriteNumberText(this Stream stream, int number, string text)
{
stream.WriteDouble(number);
stream.WriteWhiteSpace();
stream.WriteByte(Whitespace);
stream.WriteText(text);
stream.WriteNewLine();
}
@ -88,7 +93,7 @@
public static void WriteNumberText(this Stream stream, int number, ReadOnlySpan<byte> asciiBytes)
{
stream.WriteDouble(number);
stream.WriteWhiteSpace();
stream.WriteByte(Whitespace);
stream.WriteText(asciiBytes);
stream.WriteNewLine();
}
@ -96,7 +101,7 @@
public static void WriteNumberText(this Stream stream, double number, string text)
{
stream.WriteDouble(number);
stream.WriteWhiteSpace();
stream.WriteByte(Whitespace);
stream.WriteText(text);
stream.WriteNewLine();
}

View File

@ -27,7 +27,7 @@
Stream.SetLength(value);
}
#if NET6_0_OR_GREATER
#if NET
public override int Read(Span<byte> buffer)
{
return Stream.Read(buffer);
@ -44,7 +44,7 @@
Stream.Write(buffer, offset, count);
}
#if NET6_0_OR_GREATER
#if NET
public override void Write(ReadOnlySpan<byte> buffer)
{
Stream.Write(buffer);

View File

@ -53,7 +53,7 @@
inner.Write(buffer, offset, count);
}
#if NET6_0_OR_GREATER
#if NET
public override void Write(ReadOnlySpan<byte> buffer)
{
crc.Append(buffer);

View File

@ -139,7 +139,7 @@
/// </summary>
/// <typeparam name="TPage"></typeparam>
/// <typeparam name="TPageFactory"></typeparam>
#if NET6_0_OR_GREATER
#if NET
public void AddPageFactory<TPage, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] TPageFactory>() where TPageFactory : IPageFactory<TPage>
#else
public void AddPageFactory<TPage, TPageFactory>() where TPageFactory : IPageFactory<TPage>

View File

@ -5,7 +5,7 @@
namespace System.Diagnostics.CodeAnalysis;
#if NETSTANDARD2_0 || NETFRAMEWORK
#if !NET
internal sealed class DoesNotReturnAttribute : Attribute { }
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]

View File

@ -1,4 +1,4 @@
#if NETFRAMEWORK || NETSTANDARD2_0
#if !NET
namespace System.IO;

View File

@ -9,109 +9,98 @@
internal static class ToUnicodeCMapBuilder
{
private const string BeginToken = "begin";
private const string BeginCMapToken = "begincmap";
private const string DefToken = "def";
private const string DictToken = "dict";
private const string FindResourceToken = "findresource";
private static ReadOnlySpan<byte> BeginToken => "begin"u8;
private static ReadOnlySpan<byte> BeginCMapToken => "begincmap"u8;
private static ReadOnlySpan<byte> DefToken => "def"u8;
private static ReadOnlySpan<byte> DictToken => "dict"u8;
private static ReadOnlySpan<byte> FindResourceToken => "findresource"u8;
private static readonly TokenWriter TokenWriter = new TokenWriter();
public static byte[] ConvertToCMapStream(IReadOnlyDictionary<char, byte> unicodeToCharacterCode)
{
using (var memoryStream = new MemoryStream())
using var memoryStream = new MemoryStream();
TokenWriter.WriteToken(NameToken.CidInit, memoryStream);
TokenWriter.WriteToken(NameToken.ProcSet, memoryStream);
memoryStream.WriteText(FindResourceToken, true);
memoryStream.WriteText(BeginToken);
memoryStream.WriteNewLine();
memoryStream.WriteDouble(12);
memoryStream.WriteWhiteSpace();
memoryStream.WriteText(DictToken, true);
memoryStream.WriteText(BeginToken);
memoryStream.WriteNewLine();
memoryStream.WriteText(BeginCMapToken);
memoryStream.WriteNewLine();
TokenWriter.WriteToken(NameToken.CidSystemInfo, memoryStream);
var dictionary = new DictionaryToken(new Dictionary<NameToken, IToken> {
{ NameToken.Registry, new StringToken("Adobe") },
{ NameToken.Ordering, new StringToken("UCS") },
{ NameToken.Supplement, new NumericToken(0) }
});
TokenWriter.WriteToken(dictionary, memoryStream);
memoryStream.WriteWhiteSpace();
memoryStream.WriteText(DefToken);
memoryStream.WriteNewLine();
TokenWriter.WriteToken(NameToken.Cmapname, memoryStream);
TokenWriter.WriteToken(NameToken.Create("Adobe-Identity-UCS"), memoryStream);
memoryStream.WriteText(DefToken);
memoryStream.WriteNewLine();
TokenWriter.WriteToken(NameToken.CmapType, memoryStream);
memoryStream.WriteNumberText(2, DefToken);
memoryStream.WriteNumberText(1, "begincodespacerange"u8);
TokenWriter.WriteToken(new HexToken(['0', '0']), memoryStream);
TokenWriter.WriteToken(new HexToken(['F', 'F']), memoryStream);
memoryStream.WriteNewLine();
memoryStream.WriteText("endcodespacerange"u8);
memoryStream.WriteNewLine();
memoryStream.WriteNumberText(unicodeToCharacterCode.Count, "beginbfchar"u8);
foreach (var keyValuePair in unicodeToCharacterCode)
{
TokenWriter.WriteToken(NameToken.CidInit, memoryStream);
TokenWriter.WriteToken(NameToken.ProcSet, memoryStream);
memoryStream.WriteText(FindResourceToken, true);
memoryStream.WriteText(BeginToken);
var unicodeInt = (ushort)keyValuePair.Key;
var low = (byte)(unicodeInt >> 0);
var high = (byte)(unicodeInt >> 8);
var from = Hex.GetString([keyValuePair.Value]);
var to = Hex.GetString([high, low]);
TokenWriter.WriteToken(new HexToken(from.AsSpan()), memoryStream);
TokenWriter.WriteToken(new HexToken(to.AsSpan()), memoryStream);
memoryStream.WriteNewLine();
memoryStream.WriteDouble(12);
memoryStream.WriteWhiteSpace();
memoryStream.WriteText(DictToken, true);
memoryStream.WriteText(BeginToken);
memoryStream.WriteNewLine();
memoryStream.WriteText(BeginCMapToken);
memoryStream.WriteNewLine();
TokenWriter.WriteToken(NameToken.CidSystemInfo, memoryStream);
var dictionary = new DictionaryToken(new Dictionary<NameToken, IToken>
{
{ NameToken.Registry, new StringToken("Adobe") },
{ NameToken.Ordering, new StringToken("UCS") },
{ NameToken.Supplement, new NumericToken(0) }
});
TokenWriter.WriteToken(dictionary, memoryStream);
memoryStream.WriteWhiteSpace();
memoryStream.WriteText(DefToken);
memoryStream.WriteNewLine();
TokenWriter.WriteToken(NameToken.Cmapname, memoryStream);
TokenWriter.WriteToken(NameToken.Create("Adobe-Identity-UCS"), memoryStream);
memoryStream.WriteText(DefToken);
memoryStream.WriteNewLine();
TokenWriter.WriteToken(NameToken.CmapType, memoryStream);
memoryStream.WriteNumberText(2, DefToken);
memoryStream.WriteNumberText(1, "begincodespacerange"u8);
TokenWriter.WriteToken(new HexToken(['0', '0']), memoryStream);
TokenWriter.WriteToken(new HexToken(['F', 'F']), memoryStream);
memoryStream.WriteNewLine();
memoryStream.WriteText("endcodespacerange"u8);
memoryStream.WriteNewLine();
memoryStream.WriteNumberText(unicodeToCharacterCode.Count, "beginbfchar"u8);
foreach (var keyValuePair in unicodeToCharacterCode)
{
var unicodeInt = (ushort) keyValuePair.Key;
var low = (byte) (unicodeInt >> 0);
var high = (byte) (unicodeInt >> 8);
var from = Hex.GetString([keyValuePair.Value]);
var to = Hex.GetString([high, low]);
TokenWriter.WriteToken(new HexToken(from.AsSpan()), memoryStream);
TokenWriter.WriteToken(new HexToken(to.AsSpan()), memoryStream);
memoryStream.WriteNewLine();
}
memoryStream.WriteText("endbfchar"u8);
memoryStream.WriteNewLine();
memoryStream.WriteText("endcmap"u8);
memoryStream.WriteNewLine();
memoryStream.WriteText("CMapName currentdict /CMap defineresource pop"u8);
memoryStream.WriteNewLine();
memoryStream.WriteText("end"u8);
memoryStream.WriteNewLine();
memoryStream.WriteText("end"u8);
memoryStream.WriteNewLine();
return memoryStream.ToArray();
}
memoryStream.WriteText("endbfchar"u8);
memoryStream.WriteNewLine();
memoryStream.WriteText("endcmap"u8);
memoryStream.WriteNewLine();
memoryStream.WriteText("CMapName currentdict /CMap defineresource pop"u8);
memoryStream.WriteNewLine();
memoryStream.WriteText("end"u8);
memoryStream.WriteNewLine();
memoryStream.WriteText("end"u8);
memoryStream.WriteNewLine();
return memoryStream.ToArray();
}
}
}
}

View File

@ -1,11 +1,11 @@
namespace UglyToad.PdfPig.Writer
{
using Core;
using Graphics.Operations;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using Core;
using Graphics.Operations;
using Tokens;
/// <summary>
@ -85,8 +85,8 @@
{
recordVersion?.Invoke(version);
WriteString($"%PDF-{version.ToString("0.0", CultureInfo.InvariantCulture)}", Stream);
Stream.WriteText($"%PDF-{version.ToString("0.0", CultureInfo.InvariantCulture)}");
Stream.WriteNewLine();
Stream.WriteText("%"u8);
Stream.Write([169, 205, 196, 210]);
Stream.WriteNewLine();
@ -98,12 +98,6 @@
TokenWriter.WriteCrossReferenceTable(offsets, catalogReference.Data, Stream, documentInformationReference?.Data);
}
private static void WriteString(string text, Stream stream)
{
var bytes = OtherEncodings.StringAsLatin1Bytes(text);
stream.Write(bytes, 0, bytes.Length);
stream.WriteNewLine();
}
public void Dispose()
{

View File

@ -64,7 +64,7 @@
private static ReadOnlySpan<byte> TrueBytes => "true"u8;
private static readonly byte Whitespace = (byte)' ';
private const byte Whitespace = (byte)' ';
private static ReadOnlySpan<byte> Xref => "xref"u8;
@ -219,12 +219,11 @@
* n is a literal keyword identifying this as an in-use entry
* eol is a 2-character end-of-line sequence ('\r\n' or ' \n')
*/
var paddedOffset = OtherEncodings.StringAsLatin1Bytes(offset.Offset.ToString("D10", CultureInfo.InvariantCulture));
var paddedOffset = Encoding.ASCII.GetBytes(offset.Offset.ToString("D10", CultureInfo.InvariantCulture));
outputStream.Write(paddedOffset);
outputStream.WriteWhiteSpace();
WriteWhitespace(outputStream);
var generation = OtherEncodings.StringAsLatin1Bytes(offset.Generation.ToString("D5", CultureInfo.InvariantCulture));
var generation = Encoding.ASCII.GetBytes(offset.Generation.ToString("D5", CultureInfo.InvariantCulture));
outputStream.Write(generation);
WriteWhitespace(outputStream);
@ -289,10 +288,10 @@
public void WriteObject(long objectNumber, int generation, byte[] data, Stream outputStream)
{
WriteLong(objectNumber, outputStream);
WriteWhitespace(outputStream);
outputStream.WriteWhiteSpace();
WriteInt(generation, outputStream);
WriteWhitespace(outputStream);
outputStream.WriteWhiteSpace();
outputStream.Write(ObjStart);
WriteLineBreak(outputStream);
@ -321,7 +320,7 @@
protected void WriteArray(ArrayToken array, Stream outputStream)
{
outputStream.WriteByte(ArrayStart);
WriteWhitespace(outputStream);
outputStream.WriteWhiteSpace();
for (var i = 0; i < array.Data.Count; i++)
{
@ -330,7 +329,7 @@
}
outputStream.WriteByte(ArrayEnd);
WriteWhitespace(outputStream);
outputStream.WriteWhiteSpace();
}
/// <summary>
@ -340,7 +339,7 @@
{
var bytes = boolean.Data ? TrueBytes : FalseBytes;
outputStream.Write(bytes);
WriteWhitespace(outputStream);
outputStream.WriteWhiteSpace();
}
/// <summary>
@ -348,9 +347,8 @@
/// </summary>
protected void WriteComment(CommentToken comment, Stream outputStream)
{
var bytes = OtherEncodings.StringAsLatin1Bytes(comment.Data);
outputStream.WriteByte(Comment);
outputStream.Write(bytes);
outputStream.WriteText(comment.Data);
WriteLineBreak(outputStream);
}
@ -360,7 +358,7 @@
protected void WriteNullToken(Stream outputStream)
{
outputStream.Write("null"u8);
WriteWhitespace(outputStream);
outputStream.WriteWhiteSpace();
}
/// <summary>
@ -398,13 +396,13 @@
protected virtual void WriteIndirectReference(IndirectReferenceToken reference, Stream outputStream)
{
WriteLong(reference.Data.ObjectNumber, outputStream);
WriteWhitespace(outputStream);
outputStream.WriteWhiteSpace();
WriteInt(reference.Data.Generation, outputStream);
WriteWhitespace(outputStream);
outputStream.WriteWhiteSpace();
outputStream.WriteByte(RByte);
WriteWhitespace(outputStream);
outputStream.WriteWhiteSpace();
}
/// <summary>
@ -447,7 +445,7 @@
outputStream.WriteByte(NameStart);
outputStream.Write(sb.WrittenSpan);
WriteWhitespace(outputStream);
outputStream.WriteWhiteSpace();
}
/// <summary>
@ -484,10 +482,10 @@
protected virtual void WriteObject(ObjectToken objectToken, Stream outputStream)
{
WriteLong(objectToken.Number.ObjectNumber, outputStream);
WriteWhitespace(outputStream);
outputStream.WriteWhiteSpace();
WriteInt(objectToken.Number.Generation, outputStream);
WriteWhitespace(outputStream);
outputStream.WriteWhiteSpace();
outputStream.Write(ObjStart);
WriteLineBreak(outputStream);
@ -590,7 +588,7 @@
}
outputStream.WriteByte(StringEnd);
WriteWhitespace(outputStream);
outputStream.WriteWhiteSpace();
}
/// <summary>