3 This file is part of libmspdatafile
4 Copyright © 2006-2008 Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
8 #ifndef MSP_DATAFILE_LOADER_H_
9 #define MSP_DATAFILE_LOADER_H_
12 #include <msp/io/buffered.h>
13 #include <msp/io/file.h>
15 #include "loaderaction.h"
17 #include "statement.h"
23 Base class for data loaders. This class only provides core functionality.
24 You'll almost certainly want to use one of the BasicLoader classes instead.
26 Under normal circumstances, a class capable of being loaded should have a
27 nested typed called Loader which resolves to a descendant of this class. If
28 another structure is used, the loader object must be constructed manually.
30 A loader class should execute one or more calls to the various add() functions
31 to register actions with expected keywords. Currently possible actions are
32 calling a function of the loader, storing values in member variables of an
33 object and ignoring the statement. If a unexpected keyword is encountered, an
34 exception is thrown and the loading is aborted.
36 A sub-object can be loaded with one of the load_sub functions.
38 When loading has finished successfully, the virtual function finish() is
39 called. Any post-processing of the data should be placed here and not in the
42 See also classes BasicLoader and BasicLoader2.
48 Loads data from a statement. This is normally only used by the Loader class
49 itself for loading sub-items, but needs to be public so it can be accessed
52 void load(const Statement &st);
55 Loads statements from a parser.
61 Loader(): cur_st(0) { }
64 Adds a keyword that is loaded with a zero-argument function.
67 void add(const std::string &k, void (L::*func)())
68 { add(k, new LoaderFunc0<L>(func)); }
70 template<typename L, typename A0>
71 void add(const std::string &k, void (L::*func)(A0))
72 { add(k, new LoaderFunc1<L, A0>(func)); }
74 template<typename L, typename A0, typename A1>
75 void add(const std::string &k, void (L::*func)(A0, A1))
76 { add(k, new LoaderFunc2<L, A0, A1>(func)); }
78 template<typename L, typename A0, typename A1, typename A2>
79 void add(const std::string &k, void (L::*func)(A0, A1, A2))
80 { add(k, new LoaderFunc3<L, A0, A1, A2>(func)); }
82 template<typename L, typename A0, typename A1, typename A2, typename A3>
83 void add(const std::string &k, void (L::*func)(A0, A1, A2, A3))
84 { add(k, new LoaderFunc4<L, A0, A1, A2, A3>(func)); }
86 template<typename L, typename A0, typename A1, typename A2, typename A3, typename A4>
87 void add(const std::string &k, void (L::*func)(A0, A1, A2, A3, A4))
88 { add(k, new LoaderFunc5<L, A0, A1, A2, A3, A4>(func)); }
91 Adds a keyword that is loaded into a variable of the loaded object.
93 template<typename L, typename T0>
94 void add(const std::string &k, T0 L::*p0)
95 { add(k, new LoadValue1<L, T0>(p0)); }
97 template<typename L, typename T0, typename T1>
98 void add(const std::string &k, T0 L::*p0, T1 L::*p1)
99 { add(k, new LoadValue2<L, T0, T1>(p0, p1)); }
102 Adds a keyword that is recognized but ignored.
104 void add(const std::string &k)
108 Loads a sub-object from the statement being processed. The Loader class of
109 the sub-object is automatically used.
114 typename S::Loader ldr(s);
119 Loads a sub-object from the statement being processed with an extra parameter
120 for the Loader. The Loader class of the sub-object is automatically used.
122 template<typename S, typename T>
123 void load_sub(S &s, T &p)
125 typename S::Loader ldr(s, p);
130 Processes the current statement's substatements with another Loader.
132 void load_sub_with(Loader &);
135 Returns the source of the statement being processed. This can be used to
136 implement relative paths in include-like statements. Note that the source
137 may not necessarily be a file.
139 const std::string &get_source() const
142 throw InvalidState("get_source called without current statement");
143 return cur_st->source;
146 virtual void finish() { }
148 typedef std::map<std::string, LoaderAction *> ActionMap;
151 const Statement *cur_st;
153 void add(const std::string &, LoaderAction *);
154 void load_statement(const Statement &st);
159 Provides the basic functionality of an object loader. Deriving from this
160 allows loading values directly into member variables of the objects.
163 class BasicLoader: public Loader
172 BasicLoader(O &o): obj(o) { }
173 O &get_object() const { return obj; }
178 Provides functionality for loading objects with a Collection. Deriving from
179 this allows loading pointers to objects in the collection automatically.
181 template<typename O, typename C>
182 class BasicLoader2: public BasicLoader<O>
185 typedef C Collection;
191 BasicLoader2(O &o, C &c): BasicLoader<O>(o), coll(c) { }
192 C &get_collection() const { return coll; }
197 Loads an object from a file. The object must have a public Loader class.
200 void load(T &obj, const std::string &fn)
203 IO::Buffered buf(in);
205 Parser parser(buf, fn);
206 typename T::Loader loader(obj);
210 template<typename T, typename U>
211 void load(T &obj, const std::string &fn, U &arg)
214 IO::Buffered buf(in);
216 Parser parser(buf, fn);
217 typename T::Loader loader(obj, arg);
221 } // namespace DataFile