Skip to content

Commit

Permalink
Merge pull request #416 from iamcarbon/bplist1
Browse files Browse the repository at this point in the history
Spanify BplistReader
  • Loading branch information
drewnoakes authored Feb 23, 2024
2 parents ec5fe3c + 3cccae2 commit 5fe5981
Show file tree
Hide file tree
Showing 6 changed files with 18 additions and 33 deletions.
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

0 comments on commit 5fe5981

Please sign in to comment.