Added callbacks to TagReader class to permit user-handled parsing
This commit is contained in:
parent
778d15f44b
commit
a3e5ce5f5a
|
@ -0,0 +1,34 @@
|
||||||
|
using System;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
|
||||||
|
namespace SharpNBT
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Arguments supplied with tag-related events.
|
||||||
|
/// </summary>
|
||||||
|
public class TagEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a constant describing the basic NBT type of the tag.
|
||||||
|
/// </summary>
|
||||||
|
public TagType Type { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the parsed <see cref="Tag"/> instance.
|
||||||
|
/// </summary>
|
||||||
|
[NotNull]
|
||||||
|
public Tag Tag { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="TagEventArgs"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">A constant describing the basic NBT type of the tag.</param>
|
||||||
|
/// <param name="tag">The parsed <see cref="Tag"/> instance.</param>
|
||||||
|
/// <exception cref="ArgumentNullException">Thrown when <paramref name="tag"/> is <see langword="null"/>.</exception>
|
||||||
|
public TagEventArgs(TagType type, [NotNull] Tag tag)
|
||||||
|
{
|
||||||
|
Type = type;
|
||||||
|
Tag = tag ?? throw new ArgumentNullException(nameof(tag));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.IO;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
|
||||||
|
namespace SharpNBT
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Arguments supplied when an event that can be handled by an event subscriber.
|
||||||
|
/// </summary>
|
||||||
|
public class TagHandledEventArgs : HandledEventArgs
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a constant describing the basic NBT type of the tag.
|
||||||
|
/// </summary>
|
||||||
|
public TagType Type { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets flag indicating if this tag is named, only <see langowrd="false"/> when a tag is a direct child of a <see cref="ListTag"/>.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsNamed { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the stream being read from, positioned at the beginning of the tag payload.
|
||||||
|
/// <para/>
|
||||||
|
/// When handling this event, the stream position must be moved to the end of the payload, ready for the next tag to be parsed.
|
||||||
|
/// </summary>
|
||||||
|
[NotNull]
|
||||||
|
public Stream Stream { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the resulting tag from this event being handled.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>This property <b>must</b> set to a non-null value when <see cref="HandledEventArgs.Handled"/> is <see langword="true"/>.</remarks>
|
||||||
|
[CanBeNull]
|
||||||
|
public Tag Result { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="TagHandledEventArgs"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">A constant describing the basic NBT type of the tag.</param>
|
||||||
|
/// <param name="isNamed">Flag indicating if this tag is named, only <see langowrd="false"/> when a tag is a direct child of a <see cref="ListTag"/>.</param>
|
||||||
|
/// <param name="stream">The stream being read from, positioned at the beginning of the tag payload.</param>
|
||||||
|
/// <exception cref="ArgumentNullException">Thrown when <paramref name="stream"/> is <see langword="null"/>.</exception>
|
||||||
|
public TagHandledEventArgs(TagType type, bool isNamed, [NotNull] Stream stream)
|
||||||
|
{
|
||||||
|
Type = type;
|
||||||
|
IsNamed = isNamed;
|
||||||
|
Stream = stream ?? throw new ArgumentNullException(nameof(stream));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace SharpNBT
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Handler for events used with the <see cref="TagReader"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">A type derived from <see cref="EventArgs"/>.</typeparam>
|
||||||
|
/// <param name="reader">The <see cref="TagReader"/> instance invoking the event.</param>
|
||||||
|
/// <param name="args">Any relevant args to be supplied with the callback,</param>
|
||||||
|
public delegate void TagReaderCallback<in T>(TagReader reader, T args) where T : EventArgs;
|
||||||
|
}
|
|
@ -7,12 +7,7 @@ using JetBrains.Annotations;
|
||||||
|
|
||||||
namespace SharpNBT
|
namespace SharpNBT
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Delegate type for tag-related events that can occur within the <see cref="TagReader"/> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <seealso cref="TagReader.TagRead"/>
|
|
||||||
public delegate void TagReadCallback(TagReader reader, TagType type, Tag tag);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provides methods for reading NBT data from a stream.
|
/// Provides methods for reading NBT data from a stream.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -22,7 +17,9 @@ namespace SharpNBT
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs when a tag has been fully deserialized from the stream.
|
/// Occurs when a tag has been fully deserialized from the stream.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event TagReadCallback TagRead;
|
public event TagReaderCallback<TagEventArgs> TagRead;
|
||||||
|
|
||||||
|
public event TagReaderCallback<TagHandledEventArgs> TagEncountered;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the underlying stream this <see cref="TagReader"/> is operating on.
|
/// Gets the underlying stream this <see cref="TagReader"/> is operating on.
|
||||||
|
@ -351,6 +348,13 @@ namespace SharpNBT
|
||||||
[NotNull]
|
[NotNull]
|
||||||
private Tag ReadTag(TagType type, bool named)
|
private Tag ReadTag(TagType type, bool named)
|
||||||
{
|
{
|
||||||
|
var result = OnTagEncountered(type, named);
|
||||||
|
if (result != null)
|
||||||
|
{
|
||||||
|
OnTagRead(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
Tag tag = type switch
|
Tag tag = type switch
|
||||||
{
|
{
|
||||||
TagType.End => new EndTag(),
|
TagType.End => new EndTag(),
|
||||||
|
@ -447,7 +451,19 @@ namespace SharpNBT
|
||||||
/// Invokes the <see cref="TagRead"/> event when a tag has been fully deserialized from the <see cref="BaseStream"/>.
|
/// Invokes the <see cref="TagRead"/> event when a tag has been fully deserialized from the <see cref="BaseStream"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="tag">The deserialized <see cref="Tag"/> instance.</param>
|
/// <param name="tag">The deserialized <see cref="Tag"/> instance.</param>
|
||||||
protected virtual void OnTagRead(Tag tag) => TagRead?.Invoke(this, tag.Type, tag);
|
protected virtual void OnTagRead(Tag tag) => TagRead?.Invoke(this, new TagEventArgs(tag.Type, tag));
|
||||||
|
|
||||||
|
[CanBeNull]
|
||||||
|
protected virtual Tag OnTagEncountered(TagType type, bool named)
|
||||||
|
{
|
||||||
|
// Early out if no subscribers.
|
||||||
|
if (TagEncountered is null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var args = new TagHandledEventArgs(type, named, BaseStream);
|
||||||
|
TagEncountered.Invoke(this, args);
|
||||||
|
return args.Handled ? args.Result : null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue