- Fixed SNBT bug that would not parse boolean values

- Implemented BoolTag type for convenience
- Implemented compiled regular expressions
This commit is contained in:
ForeverZer0 2021-09-18 18:46:43 -04:00
parent 7a1d6c0471
commit f27bebf6c9
9 changed files with 95 additions and 4 deletions

View File

@ -1,4 +1,5 @@
{
"bool test": true,
"test case": 90,
noQuotes: "HELLO WORLD THIS IS A TEST STRING ÅÄÖ!",
"test with \" escaped quote": 90,

View File

@ -30,6 +30,8 @@ namespace SharpNBT.Tests
.BeginCompound("egg").AddString("name", "Eggbert").AddFloat("value", 0.5f).EndCompound()
.BeginCompound("ham").AddString("name", "Hampus").AddFloat("value", 0.75f).EndCompound()
.EndCompound()
.AddBool("boolTest", true)
.AddBool("bool Test 2", false)
.AddInt("iniTest", 2147483647)
.AddByte("byteTest", 127)
.AddString("stringTest", "HELLO WORLD THIS IS A TEST STRING \xc5\xc4\xd6!")

View File

@ -24,7 +24,7 @@ namespace SharpNBT.SNBT
public LexerRule(TokenType type, string pattern, ResultHandler handler, bool skipped = false)
{
Type = type;
Pattern = new Regex(pattern);
Pattern = new Regex(pattern, RegexOptions.Compiled);
IsSkipped = skipped;
processResult = handler;
}

View File

@ -36,6 +36,7 @@ namespace SharpNBT.SNBT
lexer.AddRule(TokenType.EndArray, @"\]");
lexer.AddRule(TokenType.Float, @"(-?[0-9]*\.[0-9]+)[Ff]", FirstGroupValue);
lexer.AddRule(TokenType.Double, @"(-?[0-9]*\.[0-9]+)[Dd]?", FirstGroupValue);
lexer.AddRule(TokenType.Bool, "(true|false)", FirstGroupValue);
lexer.AddRule(TokenType.Byte, "(-?[0-9]+)[Bb]", FirstGroupValue);
lexer.AddRule(TokenType.Short, "(-?[0-9]+)[Ss]", FirstGroupValue);
lexer.AddRule(TokenType.Long, "(-?[0-9]+)[Ll]", FirstGroupValue);
@ -142,6 +143,7 @@ namespace SharpNBT.SNBT
TokenType.IntArray => ParseIntArray(name, queue),
TokenType.LongArray => ParseLongArray(name, queue),
TokenType.List => ParseList(name, queue),
TokenType.Bool => new BoolTag(name, bool.Parse(token.Value)),
TokenType.Byte => new ByteTag(name, sbyte.Parse(token.Value)),
TokenType.Short => new ShortTag(name, short.Parse(token.Value)),
TokenType.Int => new IntTag(name, int.Parse(token.Value)),

View File

@ -70,6 +70,11 @@ namespace SharpNBT.SNBT
/// </summary>
Byte,
/// <summary>
/// A <see cref="BoolTag"/> value.
/// </summary>
Bool,
/// <summary>
/// A <see cref="ShortTag"/> value.
/// </summary>

View File

@ -13,7 +13,9 @@
<PackageTags>nbt;named binary tag;minecraft;serialization;java;bedrock;pocket edition;varint;varlong;zlib</PackageTags>
<Copyright>Copyright © Eric Freed 2021</Copyright>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageVersion>1.1.0</PackageVersion>
<PackageVersion>1.2.0</PackageVersion>
<AssemblyVersion>1.2.0</AssemblyVersion>
<FileVersion>1.2.0</FileVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">

View File

@ -36,6 +36,21 @@ namespace SharpNBT
tree.Push(root);
}
/// <summary>
/// Adds a new <see cref="ByteTag"/> with the specified <paramref name="name"/> and <paramref name="value"/> to the tree at the current depth.
/// </summary>
/// <param name="name">The name of the node to add.</param>
/// <param name="value">The value of the tag.</param>
/// <returns>Returns this <see cref="TagBuilder"/> instance for chaining.</returns>
public TagBuilder AddBool([CanBeNull] string name, bool value) => AddTag(new BoolTag(name, value));
/// <summary>
/// Adds a new unnamed <see cref="ByteTag"/> with the specified <paramref name="value"/> to the tree at the current depth.
/// </summary>
/// <param name="value">The value of the tag.</param>
/// <returns>Returns this <see cref="TagBuilder"/> instance for chaining.</returns>
public TagBuilder AddBool(bool value) => AddBool(null, value);
/// <summary>
/// Adds a new <see cref="ByteTag"/> with the specified <paramref name="name"/> and <paramref name="value"/> to the tree at the current depth.
/// </summary>

56
SharpNBT/Tags/BoolTag.cs Normal file
View File

@ -0,0 +1,56 @@
using System;
using System.Runtime.Serialization;
using JetBrains.Annotations;
namespace SharpNBT
{
/// <summary>
/// A tag that contains a single 8-bit integer value.
/// </summary>
/// <remarks>
/// This tag type does not exist in the NBT specification, and is included for convenience to differentiate it from the <see cref="ByteTag"/> that it is
/// actually serialized as.
/// </remarks>
[PublicAPI][Serializable]
public class BoolTag : Tag<bool>
{
private const string TRUE = "true";
private const string FALSE = "false";
/// <summary>
/// Creates a new instance of the <see cref="SharpNBT.ByteTag"/> class with the specified <paramref name="value"/>.
/// </summary>
/// <param name="name">The name of the tag, or <see langword="null"/> if tag has no name.</param>
/// <param name="value">The value to assign to this tag.</param>
public BoolTag([CanBeNull] string name, bool value) : base(TagType.Byte, name, value)
{
}
/// <summary>
/// Required constructor for ISerializable implementation.
/// </summary>
/// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo" /> to describing this instance.</param>
/// <param name="context">The destination (see <see cref="T:System.Runtime.Serialization.StreamingContext" />) for this serialization.</param>
protected BoolTag(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
/// <inheritdoc cref="object.ToString"/>
public override string ToString() => $"TAG_Bool({PrettyName}): {(Value ? TRUE : FALSE)}";
/// <summary>
/// Implicit conversion of this tag to a <see cref="byte"/>.
/// </summary>
/// <param name="tag">The tag to convert.</param>
/// <returns>The tag represented as a <see cref="byte"/>.</returns>
public static implicit operator bool(BoolTag tag) => tag.Value;
/// <summary>
/// Gets the <i>string</i> representation of this NBT tag (SNBT).
/// </summary>
/// <returns>This NBT tag in SNBT format.</returns>
/// <seealso href="https://minecraft.fandom.com/wiki/NBT_format#SNBT_format"/>
public override string Stringify() => $"{StringifyName}{(Value ? TRUE : FALSE)}";
}
}

View File

@ -19,6 +19,14 @@ namespace SharpNBT
[PublicAPI][Serializable]
public abstract class Tag : IEquatable<Tag>, ISerializable, ICloneable
{
private static Regex simpleNameMatcher;
static Tag()
{
simpleNameMatcher = new Regex(@"^[A-Ba-z0-9_-]+$", RegexOptions.Compiled);
}
private static IEnumerable<Type> GetKnownTypes()
{
return new[]
@ -229,7 +237,7 @@ namespace SharpNBT
{
if (string.IsNullOrEmpty(Name))
return string.Empty;
return Regex.IsMatch(Name, @"^[A-Ba-z0-9_-]+$") ? $"{Name}: " : $"\"{Name}\": ";
return simpleNameMatcher.IsMatch(Name) ? $"{Name}: " : $"\"{Name}\": ";
}
}
}