File: serialization.cpp

package info (click to toggle)
k3d 0.4.3.0-3
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 51,716 kB
  • ctags: 81,610
  • sloc: cpp: 283,698; ansic: 64,095; xml: 61,533; sh: 9,026; makefile: 5,282; python: 431; perl: 308; awk: 130
file content (190 lines) | stat: -rw-r--r-- 5,975 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
#include "idag.h"
#include "idocument.h"
#include "igeometry_read_format.h"
#include "igeometry_write_format.h"
#include "iobject_collection.h"
#include "iproperty.h"
#include "iproperty_collection.h"
#include "iobject.h"
#include "property.h"
#include "result.h"
#include "serialization.h"

#include <sdpxml/sdpxml.h>
#include <boost/lexical_cast.hpp>

namespace
{

class save_dependencies
{
public:
	typedef std::map<k3d::iproperty*, k3d::iobject*> map_t;

	save_dependencies(map_t& Map, sdpxml::Element& DAGXML) :
		m_map(Map),
		m_dag_xml(DAGXML)
	{
	}
	
	void operator()(const k3d::idag::dependency_t& Dependency)
	{
		// Sanity checks ...
		k3d::iproperty* const from_property = Dependency.second;
		if(!from_property)
			return;
		k3d::iobject* const from_object = m_map[from_property];
		return_if_fail(from_object);
			
		k3d::iproperty* const to_property = Dependency.first;
		return_if_fail(to_property);
		k3d::iobject* const to_object = m_map[to_property];
		return_if_fail(to_object);
		
		m_dag_xml.Append(
			sdpxml::Element("dependency", "",
				sdpxml::Attribute("from_object", boost::lexical_cast<sdpString>(from_object->id())),
				sdpxml::Attribute("from_property", from_property->name()),
				sdpxml::Attribute("to_object", boost::lexical_cast<sdpString>(to_object->id())),
				sdpxml::Attribute("to_property", to_property->name())));
	}	

private:
	map_t& m_map;
	sdpxml::Element& m_dag_xml;
};

class load_dependencies
{
public:
	typedef std::map<k3d::iobject::id_type, k3d::iobject*> map_t;

	load_dependencies(map_t& Map, k3d::idag::dependencies_t& Dependencies) :
		m_map(Map),
		m_dependencies(Dependencies)
	{
	}

	void operator()(const sdpxml::Element& Dependency)
	{
		if("dependency" != Dependency.Name())
			return;
			
		const k3d::iobject::id_type from_object_id = sdpxml::GetAttribute(Dependency, "from_object", 0);
		return_if_fail(from_object_id);
		k3d::iobject* const from_object = m_map[from_object_id];
		if(!from_object)
			{
				std::cerr << error << "Missing dependency source object [" << from_object_id << "]" << std::endl;
				return;
			}
			
		sdpString from_property_name;
		return_if_fail(sdpxml::ParseAttribute(Dependency, "from_property", from_property_name));
		k3d::iproperty* const from_property = k3d::get_property(*from_object, from_property_name);
		if(!from_property)
			{
				std::cerr << error << "Missing dependency source property [" << from_object->name() << "." << from_property_name << "]" << std::endl;
				return;
			}
		
		const k3d::iobject::id_type to_object_id = sdpxml::GetAttribute(Dependency, "to_object", 0);
		return_if_fail(to_object_id);
		k3d::iobject* const to_object = m_map[to_object_id];
		if(!to_object)
			{
				std::cerr << error << "Missing dependency target object [" << to_object_id << "]" << std::endl;
				return;
			}
		
		sdpString to_property_name;
		return_if_fail(sdpxml::ParseAttribute(Dependency, "to_property", to_property_name));
		k3d::iproperty* const to_property = k3d::get_property(*to_object, to_property_name);
		if(!to_property)
			{
				std::cerr << error << "Missing dependency target property [" << to_object->name() << "." << to_property_name << "]" << std::endl;
				return;
			}
		
		m_dependencies[to_property] = from_property;		
	}

private:
	map_t& m_map;
	k3d::idag::dependencies_t& m_dependencies;
};

} // namespace

namespace k3d
{

void save_dag(idocument& Document, sdpxml::Element& XML)
{
	// Create a mapping of properties to objects ...
	save_dependencies::map_t object_map;
	const iobject_collection::objects_t& objects = Document.objects().collection();
	for(iobject_collection::objects_t::const_iterator object = objects.begin(); object != objects.end(); ++object)
		{
			iproperty_collection* const property_collection = dynamic_cast<iproperty_collection*>(*object);
			if(!property_collection)
				continue;

			const iproperty_collection::properties_t properties(property_collection->properties());
			for(iproperty_collection::properties_t::const_iterator property = properties.begin(); property != properties.end(); ++property)
				object_map[*property] = *object;
		}
	
	// Save all dependencies
	sdpxml::Element& dag_xml = XML.Append(sdpxml::Element("dag"));
	std::for_each(Document.dag().dependencies().begin(), Document.dag().dependencies().end(), save_dependencies(object_map, dag_xml));
}

void load_dag(idocument& Document, sdpxml::Element& XML)
{
	// If we don't have any DAG information, we're done ...
	sdpxml::Element* const dag_xml = sdpxml::FindElement(XML, sdpxml::SameName("dag"));
	if(!dag_xml)
		return;

	// Create a mapping of IDs to objects ...
	load_dependencies::map_t object_map;
	const iobject_collection::objects_t& objects = Document.objects().collection();
	for(iobject_collection::objects_t::const_iterator object = objects.begin(); object != objects.end(); ++object)
		object_map[(*object)->id()] = *object;
	
	// Load data and update the DAG ...
	idag::dependencies_t dependencies;
	std::for_each(dag_xml->Children().begin(), dag_xml->Children().end(), load_dependencies(object_map, dependencies));
	Document.dag().set_dependencies(dependencies);
}

bool import_file(idocument& Document, igeometry_read_format& FormatFilter, const boost::filesystem::path& File)
{
	// Give the format a chance to look at the file, first ...
	if(!FormatFilter.pre_read(Document, File))
		return false;

	// Prompt the user for any options before reading ...
	if(!FormatFilter.read_options(Document, File))
		return false;

	return FormatFilter.read_file(Document, File);
}

bool export_file(idocument& Document, igeometry_write_format& FormatFilter, const boost::filesystem::path& File)
{
	// Give the format a chance to look at the file, first ...
	if(!FormatFilter.pre_write(Document, File))
		return false;

	// Prompt the user for any options before writing ...
	if(!FormatFilter.write_options(Document, File))
		return false;

	// Write the file ...
	return FormatFilter.write_file(Document, File);
}

} // namespace k3d