From 288d3a419ac04077cd74feb982ac6fc8e1798192 Mon Sep 17 00:00:00 2001 From: Justin Aquadro Date: Sun, 26 Jun 2011 06:09:23 +0000 Subject: [PATCH] Remaining NBT classes refactored and documented. --- .../SubstrateCS/Source/NBT/INBTObject.cs | 40 ++ Substrate/SubstrateCS/Source/NBT/NBT.cs | 34 -- Substrate/SubstrateCS/Source/NBT/NBTSchema.cs | 408 ------------------ .../SubstrateCS/Source/NBT/NBTVerifier.cs | 232 +++++++--- .../SubstrateCS/Source/NBT/SchemaNode.cs | 60 +++ .../SubstrateCS/Source/NBT/SchemaNodeArray.cs | 81 ++++ .../Source/NBT/SchemaNodeCompound.cs | 219 ++++++++++ .../SubstrateCS/Source/NBT/SchemaNodeList.cs | 172 ++++++++ .../Source/NBT/SchemaNodeScaler.cs | 75 ++++ .../Source/NBT/SchemaNodeString.cs | 116 +++++ .../SubstrateCS/Source/NBT/SchemaOptions.cs | 21 + .../SubstrateCS/Source/NBT/TagNodeDouble.cs | 2 +- .../SubstrateCS/Source/NBT/TagNodeString.cs | 2 +- .../SubstrateCS/Source/NBT/VerifierLogger.cs | 48 +++ Substrate/SubstrateCS/Substrate.csproj | 15 +- 15 files changed, 1025 insertions(+), 500 deletions(-) create mode 100644 Substrate/SubstrateCS/Source/NBT/INBTObject.cs delete mode 100644 Substrate/SubstrateCS/Source/NBT/NBTSchema.cs create mode 100644 Substrate/SubstrateCS/Source/NBT/SchemaNode.cs create mode 100644 Substrate/SubstrateCS/Source/NBT/SchemaNodeArray.cs create mode 100644 Substrate/SubstrateCS/Source/NBT/SchemaNodeCompound.cs create mode 100644 Substrate/SubstrateCS/Source/NBT/SchemaNodeList.cs create mode 100644 Substrate/SubstrateCS/Source/NBT/SchemaNodeScaler.cs create mode 100644 Substrate/SubstrateCS/Source/NBT/SchemaNodeString.cs create mode 100644 Substrate/SubstrateCS/Source/NBT/SchemaOptions.cs create mode 100644 Substrate/SubstrateCS/Source/NBT/VerifierLogger.cs diff --git a/Substrate/SubstrateCS/Source/NBT/INBTObject.cs b/Substrate/SubstrateCS/Source/NBT/INBTObject.cs new file mode 100644 index 0000000..57e8817 --- /dev/null +++ b/Substrate/SubstrateCS/Source/NBT/INBTObject.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Substrate.NBT +{ + /// + /// Defines methods for loading or extracting an NBT tree. + /// + /// Object type that supports this interface. + public interface INBTObject + { + /// + /// Attempt to load an NBT tree into the object without validation. + /// + /// The root node of an NBT tree. + /// The object returns itself on success, or null if the tree was unparsable. + T LoadTree (TagNode tree); + + /// + /// Attempt to load an NBT tree into the object with validation. + /// + /// The root node of an NBT tree. + /// The object returns itself on success, or null if the tree failed validation. + T LoadTreeSafe (TagNode tree); + + /// + /// Builds an NBT tree from the object's data. + /// + /// The root node of an NBT tree representing the object's data. + TagNode BuildTree (); + + /// + /// Validate an NBT tree, usually against an object-supplied schema. + /// + /// The root node of an NBT tree. + /// Status indicating whether the tree was valid for this object. + bool ValidateTree (TagNode tree); + } +} diff --git a/Substrate/SubstrateCS/Source/NBT/NBT.cs b/Substrate/SubstrateCS/Source/NBT/NBT.cs index eb0a1a3..e33102b 100644 --- a/Substrate/SubstrateCS/Source/NBT/NBT.cs +++ b/Substrate/SubstrateCS/Source/NBT/NBT.cs @@ -8,40 +8,6 @@ namespace Substrate.NBT { using Substrate.Utility; - /// - /// Defines methods for loading or extracting an NBT tree. - /// - /// Object type that supports this interface. - public interface INBTObject - { - /// - /// Attempt to load an NBT tree into the object without validation. - /// - /// The root node of an NBT tree. - /// The object returns itself on success, or null if the tree was unparsable. - T LoadTree (TagNode tree); - - /// - /// Attempt to load an NBT tree into the object with validation. - /// - /// The root node of an NBT tree. - /// The object returns itself on success, or null if the tree failed validation. - T LoadTreeSafe (TagNode tree); - - /// - /// Builds an NBT tree from the object's data. - /// - /// The root node of an NBT tree representing the object's data. - TagNode BuildTree (); - - /// - /// Validate an NBT tree, usually against an object-supplied schema. - /// - /// The root node of an NBT tree. - /// Status indicating whether the tree was valid for this object. - bool ValidateTree (TagNode tree); - } - /// /// Contains the root node of an NBT tree and handles IO of tree nodes. /// diff --git a/Substrate/SubstrateCS/Source/NBT/NBTSchema.cs b/Substrate/SubstrateCS/Source/NBT/NBTSchema.cs deleted file mode 100644 index 2f9bc19..0000000 --- a/Substrate/SubstrateCS/Source/NBT/NBTSchema.cs +++ /dev/null @@ -1,408 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Substrate.NBT -{ - [Flags] - public enum SchemaOptions - { - OPTIONAL = 0x1, - CREATE_ON_MISSING = 0x2, - } - - public abstract class SchemaNode - { - private string _name; - private SchemaOptions _options; - - public string Name - { - get { return _name; } - } - - public SchemaOptions Options - { - get { return _options; } - } - - public SchemaNode (string name) - { - _name = name; - } - - public SchemaNode (string name, SchemaOptions options) - { - _name = name; - _options = options; - } - - public virtual TagNode BuildDefaultTree () - { - return null; - } - } - - public sealed class SchemaNodeScaler : SchemaNode - { - private TagType _type; - - public TagType Type - { - get { return _type; } - } - - public SchemaNodeScaler (string name, TagType type) - : base(name) - { - _type = type; - } - - public SchemaNodeScaler (string name, TagType type, SchemaOptions options) - : base(name, options) - { - _type = type; - } - - public override TagNode BuildDefaultTree () - { - switch (_type) { - case TagType.TAG_STRING: - return new TagNodeString(); - - case TagType.TAG_BYTE: - return new TagNodeByte(); - - case TagType.TAG_SHORT: - return new TagNodeShort(); - - case TagType.TAG_INT: - return new TagNodeInt(); - - case TagType.TAG_LONG: - return new TagNodeLong(); - - case TagType.TAG_FLOAT: - return new TagNodeFloat(); - - case TagType.TAG_DOUBLE: - return new TagNodeDouble(); - } - - return null; - } - } - - public sealed class SchemaNodeString : SchemaNode - { - private string _value = ""; - private int _length; - - public int Length - { - get { return _length; } - } - - public string Value - { - get { return _value; } - } - - public SchemaNodeString (string name, SchemaOptions options) - : base(name, options) - { - } - - public SchemaNodeString (string name, string value) - : base(name) - { - _value = value; - } - - public SchemaNodeString (string name, int length) - : base(name) - { - _length = length; - } - - public override TagNode BuildDefaultTree () - { - if (_value.Length > 0) { - return new TagNodeString(_value); - } - - return new TagNodeString(); - } - } - - public sealed class SchemaNodeArray : SchemaNode - { - private int _length; - - public int Length - { - get { return _length; } - } - - public SchemaNodeArray (string name) - : base(name) - { - _length = 0; - } - - public SchemaNodeArray (string name, SchemaOptions options) - : base(name, options) - { - _length = 0; - } - - public SchemaNodeArray (string name, int length) - : base(name) - { - _length = length; - } - - public SchemaNodeArray (string name, int length, SchemaOptions options) - : base(name, options) - { - _length = length; - } - - public override TagNode BuildDefaultTree () - { - return new TagNodeByteArray(new byte[_length]); - } - } - - public sealed class SchemaNodeList : SchemaNode - { - private TagType _type; - private int _length; - private SchemaNode _subschema; - - public int Length - { - get { return _length; } - } - - public TagType Type - { - get { return _type; } - } - - public SchemaNode SubSchema - { - get { return _subschema; } - } - - public SchemaNodeList (string name, TagType type) - : base(name) - { - _type = type; - } - - public SchemaNodeList (string name, TagType type, SchemaOptions options) - : base(name, options) - { - _type = type; - } - - public SchemaNodeList (string name, TagType type, int length) - : base(name) - { - _type = type; - _length = length; - } - - public SchemaNodeList (string name, TagType type, int length, SchemaOptions options) - : base(name, options) - { - _type = type; - _length = length; - } - - public SchemaNodeList (string name, TagType type, SchemaNode subschema) - : base(name) - { - _type = type; - _subschema = subschema; - } - - public SchemaNodeList (string name, TagType type, SchemaNode subschema, SchemaOptions options) - : base(name, options) - { - _type = type; - _subschema = subschema; - } - - public SchemaNodeList (string name, TagType type, int length, SchemaNode subschema) - : base(name) - { - _type = type; - _length = length; - _subschema = subschema; - } - - public SchemaNodeList (string name, TagType type, int length, SchemaNode subschema, SchemaOptions options) - : base(name, options) - { - _type = type; - _length = length; - _subschema = subschema; - } - - public override TagNode BuildDefaultTree () - { - if (_length == 0) { - return new TagNodeList(_type); - } - - TagNodeList list = new TagNodeList(_type); - for (int i = 0; i < _length; i++) { - list.Add(_subschema.BuildDefaultTree()); - } - - return list; - } - } - - public sealed class SchemaNodeCompound : SchemaNode, ICollection - { - private List _subnodes; - - #region ICollection Members - - public void Add (SchemaNode item) - { - _subnodes.Add(item); - } - - public void Clear () - { - _subnodes.Clear(); - } - - public bool Contains (SchemaNode item) - { - return _subnodes.Contains(item); - } - - public void CopyTo (SchemaNode[] array, int arrayIndex) - { - _subnodes.CopyTo(array, arrayIndex); - } - - public int Count - { - get { return _subnodes.Count; } - } - - public bool IsReadOnly - { - get { return false; } - } - - public bool Remove (SchemaNode item) - { - return _subnodes.Remove(item); - } - - #endregion - - #region IEnumerable Members - - public IEnumerator GetEnumerator () - { - return _subnodes.GetEnumerator(); - } - - #endregion - - #region IEnumerable Members - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator () - { - return _subnodes.GetEnumerator(); - } - - #endregion - - public SchemaNodeCompound () - : base("") - { - _subnodes = new List(); - } - - public SchemaNodeCompound (SchemaOptions options) - : base("", options) - { - _subnodes = new List(); - } - - public SchemaNodeCompound (string name) - : base(name) - { - _subnodes = new List(); - } - - public SchemaNodeCompound (string name, SchemaOptions options) - : base(name, options) - { - _subnodes = new List(); - } - - public SchemaNodeCompound (string name, SchemaNode subschema) - : base(name) - { - _subnodes = new List(); - - SchemaNodeCompound schema = subschema as SchemaNodeCompound; - if (schema == null) { - return; - } - - foreach (SchemaNode node in schema._subnodes) - { - _subnodes.Add(node); - } - } - - public SchemaNodeCompound (string name, SchemaNode subschema, SchemaOptions options) - : base(name, options) - { - _subnodes = new List(); - - SchemaNodeCompound schema = subschema as SchemaNodeCompound; - if (schema == null) { - return; - } - - foreach (SchemaNode node in schema._subnodes) { - _subnodes.Add(node); - } - } - - public SchemaNodeCompound MergeInto (SchemaNodeCompound tree) - { - foreach (SchemaNode node in _subnodes) { - SchemaNode f = tree._subnodes.Find(n => n.Name == node.Name); - if (f != null) { - continue; - } - tree.Add(node); - } - - return tree; - } - - public override TagNode BuildDefaultTree () - { - TagNodeCompound list = new TagNodeCompound(); - foreach (SchemaNode node in _subnodes) { - list[node.Name] = node.BuildDefaultTree(); - } - - return list; - } - } -} diff --git a/Substrate/SubstrateCS/Source/NBT/NBTVerifier.cs b/Substrate/SubstrateCS/Source/NBT/NBTVerifier.cs index b2a4bce..af9690e 100644 --- a/Substrate/SubstrateCS/Source/NBT/NBTVerifier.cs +++ b/Substrate/SubstrateCS/Source/NBT/NBTVerifier.cs @@ -4,36 +4,86 @@ using System.Text; namespace Substrate.NBT { - public delegate void MissingTagHandler (Object o, TagEventArgs e); - public delegate void InvalidTagTypeHandler (Object o, TagEventArgs e); - public delegate void InvalidTagValueHandler (Object o, TagEventArgs e); + using Substrate.Utility; - public interface INBTVerifier + /// + /// Indicates how an event processor should respond to returning event handler. + /// + public enum TagEventCode { - event MissingTagHandler MissingTag; - event InvalidTagTypeHandler InvalidTagType; - event InvalidTagValueHandler InvalidTagValue; + /// + /// The event processor should process the next event in the chian. + /// + NEXT, - bool Verify (); + /// + /// The event processor should ignore the verification failure and stop processing any remaining events. + /// + PASS, + + /// + /// The event processor should fail and stop processing any remaining events. + /// + FAIL, } + /// + /// Event arguments for failure events. + /// public class TagEventArgs : EventArgs { - protected string _tagName; - protected TagNode _tag; - protected SchemaNode _schema; + private string _tagName; + private TagNode _parent; + private TagNode _tag; + private SchemaNode _schema; + /// + /// Gets the expected name of the referenced by this event. + /// public string TagName { get { return _tagName; } } + /// + /// Gets the parent of the referenced by this event, if it exists. + /// + public TagNode Parent + { + get { return _parent; } + } + + /// + /// Gets the referenced by this event. + /// + public TagNode Tag + { + get { return _tag; } + } + + /// + /// Gets the corresponding to the referenced by this event. + /// + public SchemaNode Schema + { + get { return _schema; } + } + + /// + /// Constructs a new event argument set. + /// + /// The expected name of a . public TagEventArgs (string tagName) : base() { _tagName = tagName; } + /// + /// Constructs a new event argument set. + /// + /// The expected name of a . + /// The involved in this event. public TagEventArgs (string tagName, TagNode tag) : base() { @@ -41,6 +91,11 @@ namespace Substrate.NBT _tagName = tagName; } + /// + /// Constructs a new event argument set. + /// + /// The corresponding to the involved in this event. + /// The involved in this event. public TagEventArgs (SchemaNode schema, TagNode tag) : base() { @@ -49,35 +104,55 @@ namespace Substrate.NBT } } - public class NBTVerifier : INBTVerifier + /// + /// Verifies the integrity of an NBT tree against a schema definition. + /// + public class NBTVerifier { private TagNode _root; private SchemaNode _schema; - public event MissingTagHandler MissingTag; - public event InvalidTagTypeHandler InvalidTagType; - public event InvalidTagValueHandler InvalidTagValue; + /// + /// An event that gets fired whenever an expected is not found. + /// + public static event Func MissingTag; + + /// + /// An event that gets fired whenever an expected is of the wrong type and cannot be cast. + /// + public static event Func InvalidTagType; + + /// + /// An event that gets fired whenever an expected has a value that violates the schema. + /// + public static event Func InvalidTagValue; private Dictionary _scratch = new Dictionary(); - public NBTVerifier () { } - + /// + /// Constructs a new object for a given NBT tree and schema. + /// + /// A representing the root of an NBT tree. + /// A representing the root of a schema definition for the NBT tree. public NBTVerifier (TagNode root, SchemaNode schema) { _root = root; _schema = schema; } - public bool Verify () + /// + /// Invokes the verifier. + /// + /// Status indicating whether the NBT tree is valid for the given schema. + public virtual bool Verify () { - return Verify(_root, _schema); + return Verify(null, _root, _schema); } - private bool Verify (TagNode tag, SchemaNode schema) + private bool Verify (TagNode parent, TagNode tag, SchemaNode schema) { if (tag == null) { - OnMissingTag(new TagEventArgs(schema.Name)); - return false; + return OnMissingTag(new TagEventArgs(schema.Name)); } SchemaNodeScaler scaler = schema as SchemaNodeScaler; @@ -105,14 +180,15 @@ namespace Substrate.NBT return VerifyCompound(tag, compound); } - return false; + return OnInvalidTagType(new TagEventArgs(schema.Name, tag)); } private bool VerifyScaler (TagNode tag, SchemaNodeScaler schema) { if (!tag.IsCastableTo(schema.Type)) { - OnInvalidTagType(new TagEventArgs(schema.Name, tag)); - return false; + if (!OnInvalidTagType(new TagEventArgs(schema.Name, tag))) { + return false; + } } return true; @@ -122,16 +198,19 @@ namespace Substrate.NBT { TagNodeString stag = tag as TagNodeString; if (stag == null) { - OnInvalidTagType(new TagEventArgs(schema, tag)); - return false; + if (!OnInvalidTagType(new TagEventArgs(schema, tag))) { + return false; + } } if (schema.Length > 0 && stag.Length > schema.Length) { - OnInvalidTagValue(new TagEventArgs(schema, tag)); - return false; + if (!OnInvalidTagValue(new TagEventArgs(schema, tag))) { + return false; + } } if (schema.Value != null && stag.Data != schema.Value) { - OnInvalidTagValue(new TagEventArgs(schema, tag)); - return false; + if (!OnInvalidTagValue(new TagEventArgs(schema, tag))) { + return false; + } } return true; @@ -142,12 +221,14 @@ namespace Substrate.NBT { TagNodeByteArray atag = tag as TagNodeByteArray; if (atag == null) { - OnInvalidTagType(new TagEventArgs(schema, tag)); - return false; + if (!OnInvalidTagType(new TagEventArgs(schema, tag))) { + return false; + } } if (schema.Length > 0 && atag.Length != schema.Length) { - OnInvalidTagValue(new TagEventArgs(schema, tag)); - return false; + if (!OnInvalidTagValue(new TagEventArgs(schema, tag))) { + return false; + } } return true; @@ -157,16 +238,19 @@ namespace Substrate.NBT { TagNodeList ltag = tag as TagNodeList; if (ltag == null) { - OnInvalidTagType(new TagEventArgs(schema, tag)); - return false; + if (!OnInvalidTagType(new TagEventArgs(schema, tag))) { + return false; + } } if (ltag.Count > 0 && ltag.ValueType != schema.Type) { - OnInvalidTagValue(new TagEventArgs(schema, tag)); - return false; + if (!OnInvalidTagValue(new TagEventArgs(schema, tag))) { + return false; + } } if (schema.Length > 0 && ltag.Count != schema.Length) { - OnInvalidTagValue(new TagEventArgs(schema, tag)); - return false; + if (!OnInvalidTagValue(new TagEventArgs(schema, tag))) { + return false; + } } // Patch up empty lists @@ -180,7 +264,7 @@ namespace Substrate.NBT if (schema.SubSchema != null) { foreach (TagNode v in ltag) { - pass = Verify(v, schema.SubSchema) && pass; + pass = Verify(tag, v, schema.SubSchema) && pass; } } @@ -191,8 +275,9 @@ namespace Substrate.NBT { TagNodeCompound ctag = tag as TagNodeCompound; if (ctag == null) { - OnInvalidTagType(new TagEventArgs(schema, tag)); - return false; + if (!OnInvalidTagType(new TagEventArgs(schema, tag))) { + return false; + } } bool pass = true; @@ -211,7 +296,7 @@ namespace Substrate.NBT } } - pass = Verify(value, node) && pass; + pass = Verify(tag, value, node) && pass; } foreach (KeyValuePair item in _scratch) { @@ -225,25 +310,70 @@ namespace Substrate.NBT #region Event Handlers - protected void OnMissingTag (TagEventArgs e) + /// + /// Processes registered events for whenever an expected is not found. + /// + /// Arguments for this event. + /// Status indicating whether this event can be ignored. + protected virtual bool OnMissingTag (TagEventArgs e) { if (MissingTag != null) { - MissingTag(this, e); + foreach (Func func in MissingTag.GetInvocationList()) { + TagEventCode code = func(e); + switch (code) { + case TagEventCode.FAIL: + return false; + case TagEventCode.PASS: + return true; + } + } } + + return false; } - protected void OnInvalidTagType (TagEventArgs e) + /// + /// Processes registered events for whenever an expected is of the wrong type and cannot be cast. + /// + /// Arguments for this event. + /// Status indicating whether this event can be ignored. + protected virtual bool OnInvalidTagType (TagEventArgs e) { if (InvalidTagType != null) { - InvalidTagType(this, e); + foreach (Func func in InvalidTagType.GetInvocationList()) { + TagEventCode code = func(e); + switch (code) { + case TagEventCode.FAIL: + return false; + case TagEventCode.PASS: + return true; + } + } } + + return false; } - protected void OnInvalidTagValue (TagEventArgs e) + /// + /// Processes registered events for whenever an expected has a value that violates the schema. + /// + /// Arguments for this event. + /// Status indicating whether this event can be ignored. + protected virtual bool OnInvalidTagValue (TagEventArgs e) { if (InvalidTagValue != null) { - InvalidTagValue(this, e); + foreach (Func func in InvalidTagValue.GetInvocationList()) { + TagEventCode code = func(e); + switch (code) { + case TagEventCode.FAIL: + return false; + case TagEventCode.PASS: + return true; + } + } } + + return false; } #endregion diff --git a/Substrate/SubstrateCS/Source/NBT/SchemaNode.cs b/Substrate/SubstrateCS/Source/NBT/SchemaNode.cs new file mode 100644 index 0000000..e391185 --- /dev/null +++ b/Substrate/SubstrateCS/Source/NBT/SchemaNode.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Substrate.NBT +{ + /// + /// A node in an NBT schema definition, used to define what values are considered valid for a given NBT node. + /// + public abstract class SchemaNode + { + private string _name; + private SchemaOptions _options; + + /// + /// Gets the name of an expected NBT node. + /// + public string Name + { + get { return _name; } + } + + /// + /// Gets additional schema options defined for this node. + /// + public SchemaOptions Options + { + get { return _options; } + } + + /// + /// Constructs a new representing a named . + /// + /// The name of the corresponding . + protected SchemaNode (string name) + { + _name = name; + } + + /// + /// Constructs a new with additional options. + /// + /// The name of the corresponding . + /// One or more option flags modifying the processing of this node. + protected SchemaNode (string name, SchemaOptions options) + { + _name = name; + _options = options; + } + + /// + /// Construct a sensible default NBT tree representative of this schema node. + /// + /// A that is valid for this schema node. + public virtual TagNode BuildDefaultTree () + { + return null; + } + } +} diff --git a/Substrate/SubstrateCS/Source/NBT/SchemaNodeArray.cs b/Substrate/SubstrateCS/Source/NBT/SchemaNodeArray.cs new file mode 100644 index 0000000..83ae33f --- /dev/null +++ b/Substrate/SubstrateCS/Source/NBT/SchemaNodeArray.cs @@ -0,0 +1,81 @@ +using System; + +namespace Substrate.NBT +{ + /// + /// A concrete representing a . + /// + public sealed class SchemaNodeArray : SchemaNode + { + private int _length; + + /// + /// Gets the expected length of the corresponding byte array. + /// + public int Length + { + get { return _length; } + } + + /// + /// Indicates whether there is an expected length of the corresponding byte array. + /// + public bool HasExpectedLength + { + get { return _length > 0; } + } + + /// + /// Constructs a new representing a named . + /// + /// The name of the corresponding . + public SchemaNodeArray (string name) + : base(name) + { + _length = 0; + } + + /// + /// Constructs a new with additional options. + /// + /// The name of the corresponding . + /// One or more option flags modifying the processing of this node. + public SchemaNodeArray (string name, SchemaOptions options) + : base(name, options) + { + _length = 0; + } + + /// + /// Constructs a new representing a named with expected length . + /// + /// The name of the corresponding . + /// The expected length of corresponding byte array. + public SchemaNodeArray (string name, int length) + : base(name) + { + _length = length; + } + + /// + /// Constructs a new with additional options. + /// + /// The name of the corresponding . + /// The expected length of corresponding byte array. + /// One or more option flags modifying the processing of this node. + public SchemaNodeArray (string name, int length, SchemaOptions options) + : base(name, options) + { + _length = length; + } + + /// + /// Constructs a default satisfying the constraints of this node. + /// + /// A with a sensible default value. + public override TagNode BuildDefaultTree () + { + return new TagNodeByteArray(new byte[_length]); + } + } +} diff --git a/Substrate/SubstrateCS/Source/NBT/SchemaNodeCompound.cs b/Substrate/SubstrateCS/Source/NBT/SchemaNodeCompound.cs new file mode 100644 index 0000000..91bad22 --- /dev/null +++ b/Substrate/SubstrateCS/Source/NBT/SchemaNodeCompound.cs @@ -0,0 +1,219 @@ +using System; +using System.Collections.Generic; + +namespace Substrate.NBT +{ + /// + /// A concrete representing a . + /// + public sealed class SchemaNodeCompound : SchemaNode, ICollection + { + private List _subnodes; + + #region ICollection Members + + /// + /// Adds a as a child of this node. + /// + /// The to add. + public void Add (SchemaNode item) + { + _subnodes.Add(item); + } + + /// + /// Removes all objects from the node. + /// + public void Clear () + { + _subnodes.Clear(); + } + + /// + /// Checks if a is a child of this node. + /// + /// The to check for existance. + /// Status indicating if the exists as a child of this node. + public bool Contains (SchemaNode item) + { + return _subnodes.Contains(item); + } + + /// + /// Copies all child objects of this node to a compatible one-dimensional array, starting at the specified index of the target array. + /// + /// The one-dimensional that is the destination of the subnodes copied. The Array must have zero-based indexing. + /// The zero-based index in at which copying begins. + public void CopyTo (SchemaNode[] array, int arrayIndex) + { + _subnodes.CopyTo(array, arrayIndex); + } + + /// + /// Gets the number of child objects in this node. + /// + public int Count + { + get { return _subnodes.Count; } + } + + /// + /// Gets a value indicating whether the node is readonly. + /// + public bool IsReadOnly + { + get { return false; } + } + + /// + /// Removes the first occurance of a from this node. + /// + /// The to remove. + /// Status indicating whether a was removed. + public bool Remove (SchemaNode item) + { + return _subnodes.Remove(item); + } + + #endregion + + #region IEnumerable Members + + /// + /// Iterates through all of the objects in this . + /// + /// An enumerator for this node. + public IEnumerator GetEnumerator () + { + return _subnodes.GetEnumerator(); + } + + #endregion + + #region IEnumerable Members + + /// + /// Iterates through all of the objects in this . + /// + /// An enumerator for this node. + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator () + { + return _subnodes.GetEnumerator(); + } + + #endregion + + /// + /// Constructs a new representing a root . + /// + public SchemaNodeCompound () + : base("") + { + _subnodes = new List(); + } + + /// + /// Constructs a new with additional options. + /// + /// One or more option flags modifying the processing of this node. + public SchemaNodeCompound (SchemaOptions options) + : base("", options) + { + _subnodes = new List(); + } + + /// + /// Constructs a new representing a named . + /// + /// The name of the corresponding . + public SchemaNodeCompound (string name) + : base(name) + { + _subnodes = new List(); + } + + /// + /// Constructs a new with additional options. + /// + /// The name of the corresponding . + /// One or more option flags modifying the processing of this node. + public SchemaNodeCompound (string name, SchemaOptions options) + : base(name, options) + { + _subnodes = new List(); + } + + /// + /// Constructs a new representing a named matching the given schema. + /// + /// The name of the corresponding . + /// A representing a schema to verify against the corresponding . + public SchemaNodeCompound (string name, SchemaNode subschema) + : base(name) + { + _subnodes = new List(); + + SchemaNodeCompound schema = subschema as SchemaNodeCompound; + if (schema == null) { + return; + } + + foreach (SchemaNode node in schema._subnodes) { + _subnodes.Add(node); + } + } + + /// + /// Constructs a new with additional options. + /// + /// The name of the corresponding . + /// A representing a schema to verify against the corresponding . + /// One or more option flags modifying the processing of this node. + public SchemaNodeCompound (string name, SchemaNode subschema, SchemaOptions options) + : base(name, options) + { + _subnodes = new List(); + + SchemaNodeCompound schema = subschema as SchemaNodeCompound; + if (schema == null) { + return; + } + + foreach (SchemaNode node in schema._subnodes) { + _subnodes.Add(node); + } + } + + /// + /// Copies all the elements of this into . + /// + /// The destination to copy elements into. + /// A reference to . + public SchemaNodeCompound MergeInto (SchemaNodeCompound tree) + { + foreach (SchemaNode node in _subnodes) { + SchemaNode f = tree._subnodes.Find(n => n.Name == node.Name); + if (f != null) { + continue; + } + tree.Add(node); + } + + return tree; + } + + /// + /// Constructs a default satisfying the constraints of this node. + /// + /// A with a sensible default value. A default child is created for every contained in this . + public override TagNode BuildDefaultTree () + { + TagNodeCompound list = new TagNodeCompound(); + foreach (SchemaNode node in _subnodes) { + list[node.Name] = node.BuildDefaultTree(); + } + + return list; + } + } +} diff --git a/Substrate/SubstrateCS/Source/NBT/SchemaNodeList.cs b/Substrate/SubstrateCS/Source/NBT/SchemaNodeList.cs new file mode 100644 index 0000000..a979374 --- /dev/null +++ b/Substrate/SubstrateCS/Source/NBT/SchemaNodeList.cs @@ -0,0 +1,172 @@ +using System; + +namespace Substrate.NBT +{ + /// + /// A concrete representing a . + /// + public sealed class SchemaNodeList : SchemaNode + { + private TagType _type; + private int _length; + private SchemaNode _subschema; + + /// + /// Gets the expected number of items contained in the corresponding . + /// + public int Length + { + get { return _length; } + } + + /// + /// Gets the expected of the items contained in the corresponding . + /// + public TagType Type + { + get { return _type; } + } + + /// + /// Gets a representing a schema that items contained in the corresponding should be verified against. + /// + public SchemaNode SubSchema + { + get { return _subschema; } + } + + /// + /// Indicates whether there is an expected number of items of the corresponding . + /// + public bool HasExpectedLength + { + get { return _length > 0; } + } + + /// + /// Constructs a new representing a named containing items of type . + /// + /// The name of the corresponding . + /// The type of items contained in the corresponding . + public SchemaNodeList (string name, TagType type) + : base(name) + { + _type = type; + } + + /// + /// Constructs a new with additional options. + /// + /// The name of the corresponding . + /// The type of items contained in the corresponding . + /// One or more option flags modifying the processing of this node. + public SchemaNodeList (string name, TagType type, SchemaOptions options) + : base(name, options) + { + _type = type; + } + + /// + /// Constructs a new representing a named containing items of type . + /// + /// The name of the corresponding . + /// The type of items contained in the corresponding . + /// The number of items contained in the corresponding . + public SchemaNodeList (string name, TagType type, int length) + : base(name) + { + _type = type; + _length = length; + } + + /// + /// Constructs a new with additional options. + /// + /// The name of the corresponding . + /// The type of items contained in the corresponding . + /// The number of items contained in the corresponding . + /// One or more option flags modifying the processing of this node. + public SchemaNodeList (string name, TagType type, int length, SchemaOptions options) + : base(name, options) + { + _type = type; + _length = length; + } + + /// + /// Constructs a new representing a named containing items of type matching the given schema. + /// + /// The name of the corresponding . + /// The type of items contained in the corresponding . + /// A representing a schema to verify against items contained in the corresponding . + public SchemaNodeList (string name, TagType type, SchemaNode subschema) + : base(name) + { + _type = type; + _subschema = subschema; + } + + /// + /// Constructs a new with additional options. + /// + /// The name of the corresponding . + /// The type of items contained in the corresponding . + /// A representing a schema to verify against items contained in the corresponding . + /// One or more option flags modifying the processing of this node. + public SchemaNodeList (string name, TagType type, SchemaNode subschema, SchemaOptions options) + : base(name, options) + { + _type = type; + _subschema = subschema; + } + + /// + /// Constructs a new representing a named containing items of type matching the given schema. + /// + /// The name of the corresponding . + /// The type of items contained in the corresponding . + /// The number of items contained in the corresponding . + /// A representing a schema to verify against items contained in the corresponding . + public SchemaNodeList (string name, TagType type, int length, SchemaNode subschema) + : base(name) + { + _type = type; + _length = length; + _subschema = subschema; + } + + /// + /// Constructs a new with additional options. + /// + /// The name of the corresponding . + /// The type of items contained in the corresponding . + /// The number of items contained in the corresponding . + /// A representing a schema to verify against items contained in the corresponding . + /// One or more option flags modifying the processing of this node. + public SchemaNodeList (string name, TagType type, int length, SchemaNode subschema, SchemaOptions options) + : base(name, options) + { + _type = type; + _length = length; + _subschema = subschema; + } + + /// + /// Constructs a default satisfying the constraints of this node. + /// + /// A with a sensible default value. If a length is specified, default child objects of the necessary type will be created and added to the . + public override TagNode BuildDefaultTree () + { + if (_length == 0) { + return new TagNodeList(_type); + } + + TagNodeList list = new TagNodeList(_type); + for (int i = 0; i < _length; i++) { + list.Add(_subschema.BuildDefaultTree()); + } + + return list; + } + } +} diff --git a/Substrate/SubstrateCS/Source/NBT/SchemaNodeScaler.cs b/Substrate/SubstrateCS/Source/NBT/SchemaNodeScaler.cs new file mode 100644 index 0000000..7d591a8 --- /dev/null +++ b/Substrate/SubstrateCS/Source/NBT/SchemaNodeScaler.cs @@ -0,0 +1,75 @@ +using System; + +namespace Substrate.NBT +{ + /// + /// A concrete representing a scaler-type . + /// + public sealed class SchemaNodeScaler : SchemaNode + { + private TagType _type; + + /// + /// Gets the scaler that this node represents. + /// + public TagType Type + { + get { return _type; } + } + + /// + /// Constructs a new representing a named and of type . + /// + /// The name of the corresponding . + /// The type of the corresponding , restricted to scaler types. + public SchemaNodeScaler (string name, TagType type) + : base(name) + { + _type = type; + } + + /// + /// Constructs a new with additional options. + /// + /// The name of the corresponding . + /// The type of the corresponding , restricted to scaler types. + /// One or more option flags modifying the processing of this node. + public SchemaNodeScaler (string name, TagType type, SchemaOptions options) + : base(name, options) + { + _type = type; + } + + /// + /// Constructs a default according to the this node represents. + /// + /// A with a sensible default value. + public override TagNode BuildDefaultTree () + { + switch (_type) { + case TagType.TAG_STRING: + return new TagNodeString(); + + case TagType.TAG_BYTE: + return new TagNodeByte(); + + case TagType.TAG_SHORT: + return new TagNodeShort(); + + case TagType.TAG_INT: + return new TagNodeInt(); + + case TagType.TAG_LONG: + return new TagNodeLong(); + + case TagType.TAG_FLOAT: + return new TagNodeFloat(); + + case TagType.TAG_DOUBLE: + return new TagNodeDouble(); + } + + return null; + } + } +} diff --git a/Substrate/SubstrateCS/Source/NBT/SchemaNodeString.cs b/Substrate/SubstrateCS/Source/NBT/SchemaNodeString.cs new file mode 100644 index 0000000..fa5505b --- /dev/null +++ b/Substrate/SubstrateCS/Source/NBT/SchemaNodeString.cs @@ -0,0 +1,116 @@ +using System; + +namespace Substrate.NBT +{ + /// + /// A concrete representing a . + /// + public sealed class SchemaNodeString : SchemaNode + { + private string _value = ""; + private int _length; + + /// + /// Gets the maximum length of a valid string. + /// + public int Length + { + get { return _length; } + } + + /// + /// Gets the expected value of a valid string. + /// + /// A must be set to this value to be considered valid. + public string Value + { + get { return _value; } + } + + /// + /// Indicates whether there is a maximum-length constraint on strings in this node. + /// + public bool HasMaxLength + { + get { return _length > 0; } + } + + /// + /// Constructs a new representing a named . + /// + /// The name of the corresponding . + public SchemaNodeString (string name) + : base(name) + { + } + + /// + /// Constructs a new with additional options. + /// + /// The name of the corresponding . + /// One or more option flags modifying the processing of this node. + public SchemaNodeString (string name, SchemaOptions options) + : base(name, options) + { + } + + /// + /// Constructs a new representing a named set to . + /// + /// The name of the corresponding . + /// The value that the corresponding must be set to. + public SchemaNodeString (string name, string value) + : base(name) + { + _value = value; + } + + /// + /// Constructs a new with additional options. + /// + /// The name of the corresponding . + /// The value that the corresponding must be set to. + /// One or more option flags modifying the processing of this node. + public SchemaNodeString (string name, string value, SchemaOptions options) + : base(name, options) + { + _value = value; + } + + /// + /// Constructs a new representing a named with maximum length . + /// + /// The name of the corresponding . + /// The maximum length of strings in the corresponding . + public SchemaNodeString (string name, int length) + : base(name) + { + _length = length; + } + + /// + /// Constructs a new with additional options. + /// + /// The name of the corresponding . + /// The maximum length of strings in the corresponding . + /// One or more option flags modifying the processing of this node. + public SchemaNodeString (string name, int length, SchemaOptions options) + : base(name, options) + { + _length = length; + } + + /// + /// Constructs a default satisfying the constraints of this node. + /// + /// A with a sensible default value. If this node represents a particular string, the constructed will be set to that string. + public override TagNode BuildDefaultTree () + { + if (_value.Length > 0) { + return new TagNodeString(_value); + } + + return new TagNodeString(); + } + } +} diff --git a/Substrate/SubstrateCS/Source/NBT/SchemaOptions.cs b/Substrate/SubstrateCS/Source/NBT/SchemaOptions.cs new file mode 100644 index 0000000..a0d0114 --- /dev/null +++ b/Substrate/SubstrateCS/Source/NBT/SchemaOptions.cs @@ -0,0 +1,21 @@ +using System; + +namespace Substrate.NBT +{ + /// + /// Additional options that modify the processing of a . + /// + [Flags] + public enum SchemaOptions + { + /// + /// Any with this option will not throw an error if the corresponding is missing. + /// + OPTIONAL = 0x1, + + /// + /// If a cannot be found for a marked with this option, a sensible default will be created and inserted into the tree. + /// + CREATE_ON_MISSING = 0x2, + } +} diff --git a/Substrate/SubstrateCS/Source/NBT/TagNodeDouble.cs b/Substrate/SubstrateCS/Source/NBT/TagNodeDouble.cs index 03bbda7..3b7e92d 100644 --- a/Substrate/SubstrateCS/Source/NBT/TagNodeDouble.cs +++ b/Substrate/SubstrateCS/Source/NBT/TagNodeDouble.cs @@ -81,7 +81,7 @@ namespace Substrate.NBT /// /// Converts a system double to a double node representing the same value. /// - /// A double value. + /// A double value. /// A new double node containing the given value. public static implicit operator TagNodeDouble (double d) { diff --git a/Substrate/SubstrateCS/Source/NBT/TagNodeString.cs b/Substrate/SubstrateCS/Source/NBT/TagNodeString.cs index f1df7bb..c973863 100644 --- a/Substrate/SubstrateCS/Source/NBT/TagNodeString.cs +++ b/Substrate/SubstrateCS/Source/NBT/TagNodeString.cs @@ -89,7 +89,7 @@ namespace Substrate.NBT /// /// Converts a string node to a system string representing the same data. /// - /// A string node. + /// A string node. /// A system string set to the node's data. public static implicit operator string (TagNodeString s) { diff --git a/Substrate/SubstrateCS/Source/NBT/VerifierLogger.cs b/Substrate/SubstrateCS/Source/NBT/VerifierLogger.cs new file mode 100644 index 0000000..a44873e --- /dev/null +++ b/Substrate/SubstrateCS/Source/NBT/VerifierLogger.cs @@ -0,0 +1,48 @@ +using System; + +namespace Substrate.NBT +{ + using Substrate.Utility; + + /// + /// A collection of static methods that can be hooked into events for logging NBT errors to the console. + /// + public static class VerifierLogger + { + /// + /// Logs an occurance of a missing tag error, and advances to the next event in the event chain. + /// + /// Data about the NBT node being verified. + /// A indicating whether event processing should pass, fail, or advance. + public static TagEventCode MissingTagHandler (TagEventArgs e) + { + Console.WriteLine("Missing Tag Error: '{0}'", e.TagName); + + return TagEventCode.NEXT; + } + + /// + /// Logs an occurance of an invalid tag type error, and advances to the next event in the event chain. + /// + /// Data about the NBT node being verified. + /// A indicating whether event processing should pass, fail, or advance. + public static TagEventCode InvalidTagTypeHandler (TagEventArgs e) + { + Console.WriteLine("Invalid Tag Type Error: '{0}' has type '{1}', expected '{2}'", e.TagName, e.Tag.GetTagType(), e.Schema.ToString()); + + return TagEventCode.NEXT; + } + + /// + /// Logs an occurance of an invalid tag value error, and advances to the next event in the event chain. + /// + /// Data about the NBT node being verified. + /// A indicating whether event processing should pass, fail, or advance. + public static TagEventCode InvalidTagValueHandler (TagEventArgs e) + { + Console.WriteLine("Invalid Tag Value Error: '{0}' of type '{1}' is set to invalid value '{2}'", e.TagName, e.Tag.GetTagType(), e.Tag.ToString()); + + return TagEventCode.NEXT; + } + } +} \ No newline at end of file diff --git a/Substrate/SubstrateCS/Substrate.csproj b/Substrate/SubstrateCS/Substrate.csproj index f835b24..3d941cf 100644 --- a/Substrate/SubstrateCS/Substrate.csproj +++ b/Substrate/SubstrateCS/Substrate.csproj @@ -60,10 +60,6 @@ Assemblies\Ionic.Zlib.dll - - - - @@ -76,6 +72,14 @@ + + + + + + + + @@ -89,6 +93,7 @@ + @@ -138,7 +143,6 @@ - @@ -156,6 +160,7 @@ +