Merge pull request #59 from dcronqvist/fix-multiline-string-prop

Fix multiline string property value parsing
This commit is contained in:
dcronqvist 2024-11-17 15:13:30 +01:00 committed by GitHub
commit 080f95c698
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 198 additions and 1 deletions

View file

@ -0,0 +1,65 @@
using System.Globalization;
namespace DotTiled.Tests;
public partial class TestData
{
public static Map MapWithMultilineStringProp() => new Map
{
Class = "",
Orientation = MapOrientation.Isometric,
Width = 5,
Height = 5,
TileWidth = 32,
TileHeight = 16,
Infinite = false,
ParallaxOriginX = 0,
ParallaxOriginY = 0,
RenderOrder = RenderOrder.RightDown,
CompressionLevel = -1,
BackgroundColor = Color.Parse("#00ff00", CultureInfo.InvariantCulture),
Version = "1.10",
TiledVersion = "1.11.0",
NextLayerID = 2,
NextObjectID = 1,
Layers = [
new TileLayer
{
ID = 1,
Name = "Tile Layer 1",
Width = 5,
Height = 5,
Data = new Data
{
Encoding = DataEncoding.Csv,
GlobalTileIDs = new Optional<uint[]>([
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0
]),
FlippingFlags = new Optional<FlippingFlags[]>([
FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None,
FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None,
FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None,
FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None,
FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None
])
}
}
],
Properties =
[
new BoolProperty { Name = "boolprop", Value = true },
new ColorProperty { Name = "colorprop", Value = Color.Parse("#ff55ffff", CultureInfo.InvariantCulture) },
new FileProperty { Name = "fileprop", Value = "file.txt" },
new FloatProperty { Name = "floatprop", Value = 4.2f },
new IntProperty { Name = "intprop", Value = 8 },
new ObjectProperty { Name = "objectprop", Value = 5 },
new StringProperty { Name = "stringmultiline", Value = "hello there\n\ni am a multiline\nstring property" },
new StringProperty { Name = "stringprop", Value = "This is a string, hello world!" },
new StringProperty { Name = "unsetstringprop", Value = "" }
]
};
}

View file

@ -0,0 +1,80 @@
{ "backgroundcolor":"#00ff00",
"compressionlevel":-1,
"height":5,
"infinite":false,
"layers":[
{
"data":[0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0],
"height":5,
"id":1,
"name":"Tile Layer 1",
"opacity":1,
"type":"tilelayer",
"visible":true,
"width":5,
"x":0,
"y":0
}],
"nextlayerid":2,
"nextobjectid":1,
"orientation":"isometric",
"properties":[
{
"name":"boolprop",
"type":"bool",
"value":true
},
{
"name":"colorprop",
"type":"color",
"value":"#ff55ffff"
},
{
"name":"fileprop",
"type":"file",
"value":"file.txt"
},
{
"name":"floatprop",
"type":"float",
"value":4.2
},
{
"name":"intprop",
"type":"int",
"value":8
},
{
"name":"objectprop",
"type":"object",
"value":5
},
{
"name":"stringmultiline",
"type":"string",
"value":"hello there\n\ni am a multiline\nstring property"
},
{
"name":"stringprop",
"type":"string",
"value":"This is a string, hello world!"
},
{
"name":"unsetstringprop",
"type":"string",
"value":""
}],
"renderorder":"right-down",
"tiledversion":"1.11.0",
"tileheight":16,
"tilesets":[],
"tilewidth":32,
"type":"map",
"version":"1.10",
"width":5
}

View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.10" tiledversion="1.11.0" orientation="isometric" renderorder="right-down" width="5" height="5" tilewidth="32" tileheight="16" infinite="0" backgroundcolor="#00ff00" nextlayerid="2" nextobjectid="1">
<properties>
<property name="boolprop" type="bool" value="true"/>
<property name="colorprop" type="color" value="#ff55ffff"/>
<property name="fileprop" type="file" value="file.txt"/>
<property name="floatprop" type="float" value="4.2"/>
<property name="intprop" type="int" value="8"/>
<property name="objectprop" type="object" value="5"/>
<property name="stringmultiline">hello there
i am a multiline
string property</property>
<property name="stringprop" value="This is a string, hello world!"/>
<property name="unsetstringprop" value=""/>
</properties>
<layer id="1" name="Tile Layer 1" width="5" height="5">
<data encoding="csv">
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0
</data>
</layer>
</map>

View file

@ -42,6 +42,7 @@ public static partial class TestData
[GetMapPath("map-external-tileset-multi"), (string f) => MapExternalTilesetMulti(f), Array.Empty<ICustomTypeDefinition>()],
[GetMapPath("map-external-tileset-wangset"), (string f) => MapExternalTilesetWangset(f), Array.Empty<ICustomTypeDefinition>()],
[GetMapPath("map-with-many-layers"), (string f) => MapWithManyLayers(f), Array.Empty<ICustomTypeDefinition>()],
[GetMapPath("map-with-multiline-string-prop"), (string f) => MapWithMultilineStringProp(), Array.Empty<ICustomTypeDefinition>()],
[GetMapPath("map-with-deep-props"), (string f) => MapWithDeepProps(), MapWithDeepPropsCustomTypeDefinitions()],
[GetMapPath("map-with-class"), (string f) => MapWithClass(), MapWithClassCustomTypeDefinitions()],
[GetMapPath("map-with-class-and-props"), (string f) => MapWithClassAndProps(), MapWithClassAndPropsCustomTypeDefinitions()],

View file

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
@ -32,9 +33,14 @@ public abstract partial class TmxReaderBase
return ReadPropertyWithCustomType();
}
if (type == PropertyType.String)
{
return ReadStringProperty(name);
}
IProperty property = type switch
{
PropertyType.String => new StringProperty { Name = name, Value = r.GetRequiredAttribute("value") },
PropertyType.String => throw new InvalidOperationException("String properties should be handled elsewhere."),
PropertyType.Int => new IntProperty { Name = name, Value = r.GetRequiredAttributeParseable<int>("value") },
PropertyType.Float => new FloatProperty { Name = name, Value = r.GetRequiredAttributeParseable<float>("value") },
PropertyType.Bool => new BoolProperty { Name = name, Value = r.GetRequiredAttributeParseable<bool>("value") },
@ -49,6 +55,25 @@ public abstract partial class TmxReaderBase
});
}
internal StringProperty ReadStringProperty(string name)
{
var valueAttrib = _reader.GetOptionalAttribute("value");
if (valueAttrib.HasValue)
{
return new StringProperty { Name = name, Value = valueAttrib.Value };
}
if (!_reader.IsEmptyElement)
{
_reader.ReadStartElement("property");
var value = _reader.ReadContentAsString();
_reader.ReadEndElement();
return new StringProperty { Name = name, Value = value };
}
return new StringProperty { Name = name, Value = string.Empty };
}
internal IProperty ReadPropertyWithCustomType()
{
var isClass = _reader.GetOptionalAttribute("type") == "class";