Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spanify BplistReader #416

Merged
merged 1 commit into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 9 additions & 24 deletions MetadataExtractor/Formats/Apple/BplistReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,42 +11,27 @@ public sealed class BplistReader
// https://opensource.apple.com/source/CF/CF-550/CFBinaryPList.c
// https://synalysis.com/how-to-decode-apple-binary-property-list-files/

private static ReadOnlySpan<byte> BplistHeader => "bplist00"u8;

/// <summary>
/// Gets whether <paramref name="bplist"/> starts with the expected header bytes.
/// </summary>
public static bool IsValid(byte[] bplist)
public static bool IsValid(ReadOnlySpan<byte> bplist)
{
if (bplist.Length < BplistHeader.Length)
{
return false;
}

for (int i = 0; i < BplistHeader.Length; i++)
{
if (bplist[i] != BplistHeader[i])
{
return false;
}
}

return true;
return bplist.StartsWith("bplist00"u8);
}

public static PropertyListResults Parse(byte[] bplist)
public static PropertyListResults Parse(ReadOnlySpan<byte> bplist)
{
if (!IsValid(bplist))
{
throw new ArgumentException("Input is not a bplist.", nameof(bplist));
}

Trailer trailer = ReadTrailer();
Trailer trailer = ReadTrailer(bplist);

int offset = checked((int)(trailer.OffsetTableOffset + trailer.TopObject));
var reader = new BufferReader(bplist.AsSpan(offset), isBigEndian: true);
var reader = new BufferReader(bplist.Slice(offset), isBigEndian: true);

int[] offsets = new int[(int)trailer.NumObjects];
var offsets = new int[(int)trailer.NumObjects];

for (int i = 0; i < (int)trailer.NumObjects; i++)
{
Expand All @@ -64,7 +49,7 @@ public static PropertyListResults Parse(byte[] bplist)

for (int i = 0; i < offsets.Length; i++)
{
reader = new BufferReader(bplist.AsSpan(offsets[i]), isBigEndian: true);
reader = new BufferReader(bplist.Slice(offsets[i]), isBigEndian: true);

byte b = reader.GetByte();

Expand All @@ -90,9 +75,9 @@ public static PropertyListResults Parse(byte[] bplist)

return new PropertyListResults(objects, trailer);

Trailer ReadTrailer()
static Trailer ReadTrailer(ReadOnlySpan<byte> bplist)
{
var reader = new BufferReader(bplist.AsSpan(bplist.Length - Trailer.SizeBytes), isBigEndian: true);
var reader = new BufferReader(bplist.Slice(bplist.Length - Trailer.SizeBytes), isBigEndian: true);

// Skip 5-byte unused values, 1-byte sort version.
reader.Skip(5 + 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public sealed class AppleRunTimeMakernoteDirectory : Directory
public const int TagScale = 3;
public const int TagValue = 4;

private static readonly Dictionary<int, string> _tagNameMap = new();
private static readonly Dictionary<int, string> _tagNameMap = new(4);

static AppleRunTimeMakernoteDirectory()
{
Expand Down
4 changes: 2 additions & 2 deletions MetadataExtractor/PublicAPI/net462/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@ override MetadataExtractor.IO.IndexedCapturingReader.GetBytes(int index, System.
override MetadataExtractor.IO.IndexedSeekingReader.GetBytes(int index, System.Span<byte> bytes) -> void
override MetadataExtractor.IO.SequentialByteArrayReader.GetBytes(System.Span<byte> bytes) -> void
override MetadataExtractor.IO.SequentialStreamReader.GetBytes(System.Span<byte> bytes) -> void
static MetadataExtractor.Formats.Apple.BplistReader.IsValid(byte[]! bplist) -> bool
static MetadataExtractor.Formats.Apple.BplistReader.Parse(byte[]! bplist) -> MetadataExtractor.Formats.Apple.BplistReader.PropertyListResults!
static MetadataExtractor.Formats.Apple.BplistReader.IsValid(System.ReadOnlySpan<byte> bplist) -> bool
static MetadataExtractor.Formats.Apple.BplistReader.Parse(System.ReadOnlySpan<byte> bplist) -> MetadataExtractor.Formats.Apple.BplistReader.PropertyListResults!
static MetadataExtractor.Formats.Exif.Makernotes.AppleRunTimeMakernoteDirectory.Parse(byte[]! bytes) -> MetadataExtractor.Formats.Exif.Makernotes.AppleRunTimeMakernoteDirectory!
static MetadataExtractor.Formats.Png.PngChunkType.operator !=(MetadataExtractor.Formats.Png.PngChunkType left, MetadataExtractor.Formats.Png.PngChunkType right) -> bool
static MetadataExtractor.Formats.Png.PngChunkType.operator ==(MetadataExtractor.Formats.Png.PngChunkType left, MetadataExtractor.Formats.Png.PngChunkType right) -> bool
Expand Down
4 changes: 2 additions & 2 deletions MetadataExtractor/PublicAPI/net8.0/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@ override MetadataExtractor.IO.IndexedCapturingReader.GetBytes(int index, System.
override MetadataExtractor.IO.IndexedSeekingReader.GetBytes(int index, System.Span<byte> bytes) -> void
override MetadataExtractor.IO.SequentialByteArrayReader.GetBytes(System.Span<byte> bytes) -> void
override MetadataExtractor.IO.SequentialStreamReader.GetBytes(System.Span<byte> bytes) -> void
static MetadataExtractor.Formats.Apple.BplistReader.IsValid(byte[]! bplist) -> bool
static MetadataExtractor.Formats.Apple.BplistReader.Parse(byte[]! bplist) -> MetadataExtractor.Formats.Apple.BplistReader.PropertyListResults!
static MetadataExtractor.Formats.Apple.BplistReader.IsValid(System.ReadOnlySpan<byte> bplist) -> bool
static MetadataExtractor.Formats.Apple.BplistReader.Parse(System.ReadOnlySpan<byte> bplist) -> MetadataExtractor.Formats.Apple.BplistReader.PropertyListResults!
static MetadataExtractor.Formats.Exif.ExifReader.JpegSegmentPreamble.get -> System.ReadOnlySpan<byte>
static MetadataExtractor.Formats.Exif.Makernotes.AppleRunTimeMakernoteDirectory.Parse(byte[]! bytes) -> MetadataExtractor.Formats.Exif.Makernotes.AppleRunTimeMakernoteDirectory!
static MetadataExtractor.Formats.Icc.IccReader.JpegSegmentPreamble.get -> System.ReadOnlySpan<byte>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@ override MetadataExtractor.IO.IndexedCapturingReader.GetBytes(int index, System.
override MetadataExtractor.IO.IndexedSeekingReader.GetBytes(int index, System.Span<byte> bytes) -> void
override MetadataExtractor.IO.SequentialByteArrayReader.GetBytes(System.Span<byte> bytes) -> void
override MetadataExtractor.IO.SequentialStreamReader.GetBytes(System.Span<byte> bytes) -> void
static MetadataExtractor.Formats.Apple.BplistReader.IsValid(byte[]! bplist) -> bool
static MetadataExtractor.Formats.Apple.BplistReader.Parse(byte[]! bplist) -> MetadataExtractor.Formats.Apple.BplistReader.PropertyListResults!
static MetadataExtractor.Formats.Apple.BplistReader.IsValid(System.ReadOnlySpan<byte> bplist) -> bool
static MetadataExtractor.Formats.Apple.BplistReader.Parse(System.ReadOnlySpan<byte> bplist) -> MetadataExtractor.Formats.Apple.BplistReader.PropertyListResults!
static MetadataExtractor.Formats.Exif.Makernotes.AppleRunTimeMakernoteDirectory.Parse(byte[]! bytes) -> MetadataExtractor.Formats.Exif.Makernotes.AppleRunTimeMakernoteDirectory!
static MetadataExtractor.Formats.Png.PngChunkType.operator !=(MetadataExtractor.Formats.Png.PngChunkType left, MetadataExtractor.Formats.Png.PngChunkType right) -> bool
static MetadataExtractor.Formats.Png.PngChunkType.operator ==(MetadataExtractor.Formats.Png.PngChunkType left, MetadataExtractor.Formats.Png.PngChunkType right) -> bool
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@ override MetadataExtractor.IO.IndexedCapturingReader.GetBytes(int index, System.
override MetadataExtractor.IO.IndexedSeekingReader.GetBytes(int index, System.Span<byte> bytes) -> void
override MetadataExtractor.IO.SequentialByteArrayReader.GetBytes(System.Span<byte> bytes) -> void
override MetadataExtractor.IO.SequentialStreamReader.GetBytes(System.Span<byte> bytes) -> void
static MetadataExtractor.Formats.Apple.BplistReader.IsValid(byte[]! bplist) -> bool
static MetadataExtractor.Formats.Apple.BplistReader.Parse(byte[]! bplist) -> MetadataExtractor.Formats.Apple.BplistReader.PropertyListResults!
static MetadataExtractor.Formats.Apple.BplistReader.IsValid(System.ReadOnlySpan<byte> bplist) -> bool
static MetadataExtractor.Formats.Apple.BplistReader.Parse(System.ReadOnlySpan<byte> bplist) -> MetadataExtractor.Formats.Apple.BplistReader.PropertyListResults!
static MetadataExtractor.Formats.Exif.ExifReader.JpegSegmentPreamble.get -> System.ReadOnlySpan<byte>
static MetadataExtractor.Formats.Exif.Makernotes.AppleRunTimeMakernoteDirectory.Parse(byte[]! bytes) -> MetadataExtractor.Formats.Exif.Makernotes.AppleRunTimeMakernoteDirectory!
static MetadataExtractor.Formats.Icc.IccReader.JpegSegmentPreamble.get -> System.ReadOnlySpan<byte>
Expand Down
Loading