-
Notifications
You must be signed in to change notification settings - Fork 250
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add GetString(ReadOnlySpan<byte>) polyfill * Add ArrayPoolBufferWriter * Use Utf8.IsValid & char.IsAsciiHexDigit on NET8.0+ * Optimize HexTokenizer * Eliminate various Tuple allocations * Eliminate List allocation in CrossReferenceTable * Eliminate various allocations in Ascii85Filter * Spanify HexToken * Spanify Palette * Spanify various Cmap & font methods * Spanify Type1Charstring classes * Spanify PdfDocEncoding.TryConvertBytesToString * Spanify OctalHelpers.FromOctalDigits * Add missing braces * React to HexToken.Byte type changes * Cleanup * [Tests] React to span changes * Add ArgumentNullException check back to Type1CharstringDecryptedBytes * Remove unsafe code * Seal HexToken * Avoid allocation when passing an empty span
- Loading branch information
Showing
41 changed files
with
429 additions
and
266 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
using System; | ||
using System.Buffers; | ||
|
||
namespace UglyToad.PdfPig.Core; | ||
|
||
/// <summary> | ||
/// Pooled Buffer Writer | ||
/// </summary> | ||
public sealed class ArrayPoolBufferWriter<T> : IBufferWriter<T>, IDisposable | ||
{ | ||
private const int DefaultBufferSize = 256; | ||
|
||
private T[] buffer; | ||
private int position; | ||
|
||
/// <summary> | ||
/// PooledBufferWriter constructor | ||
/// </summary> | ||
public ArrayPoolBufferWriter() | ||
{ | ||
buffer = ArrayPool<T>.Shared.Rent(DefaultBufferSize); | ||
position = 0; | ||
} | ||
|
||
/// <summary> | ||
/// Constructs a PooledBufferWriter | ||
/// </summary> | ||
/// <param name="size">The size of the initial buffer</param> | ||
public ArrayPoolBufferWriter(int size) | ||
{ | ||
buffer = ArrayPool<T>.Shared.Rent(size); | ||
position = 0; | ||
} | ||
|
||
/// <summary> | ||
/// Advanced the current position | ||
/// </summary> | ||
/// <param name="count"></param> | ||
public void Advance(int count) | ||
{ | ||
position += count; | ||
} | ||
|
||
/// <summary> | ||
/// Writes the provided value | ||
/// </summary> | ||
public void Write(T value) | ||
{ | ||
GetSpan(1)[0] = value; | ||
|
||
position += 1; | ||
} | ||
|
||
/// <summary> | ||
/// Writes the provided values | ||
/// </summary> | ||
/// <param name="values"></param> | ||
public void Write(ReadOnlySpan<T> values) | ||
{ | ||
values.CopyTo(GetSpan(values.Length)); | ||
|
||
position += values.Length; | ||
} | ||
|
||
/// <summary> | ||
/// Returns a writeable block of memory that can be written to | ||
/// </summary> | ||
public Memory<T> GetMemory(int sizeHint = 0) | ||
{ | ||
EnsureCapacity(sizeHint); | ||
|
||
return buffer.AsMemory(position); | ||
} | ||
|
||
/// <summary> | ||
/// Returns a span that can be written to | ||
/// </summary> | ||
public Span<T> GetSpan(int sizeHint = 0) | ||
{ | ||
EnsureCapacity(sizeHint); | ||
|
||
return buffer.AsSpan(position); | ||
} | ||
|
||
/// <summary> | ||
/// Returns the number of bytes written to the buffer | ||
/// </summary> | ||
public int WrittenCount => position; | ||
|
||
/// <summary> | ||
/// Returns the committed data as Memory | ||
/// </summary> | ||
public ReadOnlyMemory<T> WrittenMemory => buffer.AsMemory(0, position); | ||
|
||
/// <summary> | ||
/// Returns the committed data as a Span | ||
/// </summary> | ||
public ReadOnlySpan<T> WrittenSpan => buffer.AsSpan(0, position); | ||
|
||
private void EnsureCapacity(int sizeHint) | ||
{ | ||
if (sizeHint is 0) | ||
{ | ||
sizeHint = 1; | ||
} | ||
|
||
if (sizeHint > RemainingBytes) | ||
{ | ||
var newBuffer = ArrayPool<T>.Shared.Rent(Math.Max(position + sizeHint, 512)); | ||
|
||
if (buffer.Length != 0) | ||
{ | ||
Array.Copy(buffer, 0, newBuffer, 0, position); | ||
ArrayPool<T>.Shared.Return(buffer); | ||
} | ||
|
||
buffer = newBuffer; | ||
} | ||
} | ||
|
||
private int RemainingBytes => buffer.Length - position; | ||
|
||
/// <summary> | ||
/// Resets the internal state so the instance can be reused before disposal | ||
/// </summary> | ||
/// <param name="clearArray"></param> | ||
public void Reset(bool clearArray = false) | ||
{ | ||
position = 0; | ||
|
||
if (clearArray) | ||
{ | ||
buffer.AsSpan().Clear(); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Disposes the buffer and returns any rented memory to the pool | ||
/// </summary> | ||
public void Dispose() | ||
{ | ||
if (buffer.Length != 0) | ||
{ | ||
ArrayPool<T>.Shared.Return(buffer); | ||
buffer = []; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
#if NETFRAMEWORK || NETSTANDARD2_0 | ||
|
||
namespace System.Text; | ||
|
||
internal static class EncodingExtensions | ||
{ | ||
public static string GetString(this Encoding encoding, ReadOnlySpan<byte> bytes) | ||
{ | ||
if (bytes.IsEmpty) | ||
{ | ||
return string.Empty; | ||
} | ||
|
||
// NOTE: this can be made allocation free by introducing unsafe | ||
return encoding.GetString(bytes.ToArray()); | ||
} | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.