From: Mattia Basaglia <mattia.basaglia@gmail.com>
Date: Sat, 6 Dec 2014 11:29:18 +0000 (+0100)
Subject: Read Properties
X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=41c6bd7ec242f518e5c4ed431015e1d0e53c78d5;p=xonotic%2Fdarkplaces.git

Read Properties
---

diff --git a/xml.c b/xml.c
index f739674e..7465aa49 100644
--- a/xml.c
+++ b/xml.c
@@ -310,6 +310,35 @@ static void xml_attribute_color( xmlNodePtr node, const char* attribute, vec3_t
 	}
 }
 
+// Read an attribute as a string
+static char* xml_attribute_string( xmlNodePtr node, const char* attribute )
+{
+	xmlChar* s;
+	char* r;
+	int size;
+	
+	size = 0;
+	r = 0;
+	if (( s = xmlGetProp(node, (xmlChar*)attribute) ))
+	{
+		// xmlChar is just an unsigned char but copy just in case
+		size = xmlStrlen(s);
+		r = malloc(size);
+		memcpy(r,s,size);
+		xmlFree(s);
+	}
+	
+	// ensure we always have a NUL-terminated string
+	if ( !size )
+	{
+		free(r);
+		r = malloc(1);
+		r[0] = 0;
+	}
+	
+	return r;
+}
+
 // x,y coordinate
 typedef struct {
 	long x;
@@ -330,18 +359,53 @@ struct Tiled_PropertyNode {
 	Tiled_PropertyNode* next;
 };
 
-typedef Tiled_PropertyNode* Tiled_Properties;
+typedef struct
+{
+	Tiled_PropertyNode* first;
+	Tiled_PropertyNode* last;
+} Tiled_Properties;
+
+// recursively clear the properties
+static void tmx_properties_clean_node(Tiled_PropertyNode* prop)
+{
+	if ( !prop )
+		return;
+	if ( prop->next )
+		tmx_properties_clean_node(prop->next);
+	free(prop->property.name);
+	free(prop->property.value);
+	free(prop);
+}
 
 // clear the properties structure
 static void tmx_properties_clean(Tiled_Properties props)
 {
-	if ( !props )
-		return;
-	if ( props->next )
-		tmx_properties_clean(props->next);
-	free(props->property.name);
-	free(props->property.value);
-	free(props);
+	tmx_properties_clean_node(props.first);
+}
+
+static void tmx_properties_insert(Tiled_Properties* out, xmlNodePtr xml)
+{
+	Tiled_PropertyNode* new_node;
+	
+	if ( strcmp((char*)xml->name,"properties") == 0  )
+	{
+		for ( xml = xml->xmlChildrenNode; xml; xml = xml->next )
+			tmx_properties_insert(out,xml);
+	}
+	else if ( strcmp((char*)xml->name,"property") == 0  )
+	{
+		new_node = malloc(sizeof(Tiled_PropertyNode));
+		new_node->property.name = xml_attribute_string(xml,"name");
+		new_node->property.value = xml_attribute_string(xml,"value");
+		new_node->next = NULL;
+		if ( out->last )
+		{
+			out->last->next = new_node;
+			out->last = new_node;
+		}
+		else
+			out->first = new_node;
+	}
 }
 
 // Image/Tile data
@@ -569,6 +633,7 @@ static Tiled_Map* tmx_map_load(const char* filename)
 	
 	map->first_layer = NULL;
 	last_layer = NULL;
+	map->properties.first = map->properties.last = NULL;
 	for ( xml_tempnode = xml_map->xmlChildrenNode; xml_tempnode; xml_tempnode = xml_tempnode->next )
 	{
 		if ( xml_tempnode->type != XML_ELEMENT_NODE )
@@ -581,7 +646,9 @@ static Tiled_Map* tmx_map_load(const char* filename)
 			curr_layer = (Tiled_Layer*)tmx_objectgroup(xml_tempnode);
 		else if ( strcmp((char*)xml_tempnode->name,"imagelayer") == 0  )
 			curr_layer = (Tiled_Layer*)tmx_imagelayer(xml_tempnode);
-		// TODO properties
+		else if ( strcmp((char*)xml_tempnode->name,"properties") == 0  )
+			tmx_properties_insert(&map->properties,xml_tempnode);
+		// TODO: tilesets
 		if ( curr_layer )
 		{
 			if ( !map->first_layer )