3 This file is part of libmspdatafile
4 Copyright © 2006-2008, 2010 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.
50 std::string signature;
52 ActionKey(const std::string &, const std::string &);
54 bool operator<(const ActionKey &) const;
57 typedef std::map<ActionKey, LoaderAction *> ActionMap;
60 const Statement *cur_st;
63 bool allow_pointer_reload;
70 bool is_pointer_reload_allowed() const { return allow_pointer_reload; }
72 /** Loads statements from a parser. */
76 /** Loads data from a statement. */
77 void load(const Statement &st);
79 /** Processes a single statement */
80 void load_statement(const Statement &st);
83 /** Loads a sub-object from the statement being processed. The Loader class
84 of the sub-object is automatically used. */
88 typename S::Loader ldr(s);
92 /** Loads a sub-object from the statement being processed with an extra
93 parameter for the Loader. The Loader class of the sub-object is
94 automatically used. */
95 template<typename S, typename T>
96 void load_sub(S &s, T &p)
98 typename S::Loader ldr(s, p);
102 /** Processes the current statement's substatements with another Loader. */
103 void load_sub_with(Loader &);
105 /** Adds a keyword that is loaded by calling a function. */
107 void add(const std::string &k, void (L::*func)())
108 { add(k, new LoaderFunc0<L>(func)); }
110 template<typename L, typename A0>
111 void add(const std::string &k, void (L::*func)(A0))
112 { add(k, new LoaderFunc1<L, A0>(func)); }
114 template<typename L, typename A0, typename A1>
115 void add(const std::string &k, void (L::*func)(A0, A1))
116 { add(k, new LoaderFunc2<L, A0, A1>(func)); }
118 template<typename L, typename A0, typename A1, typename A2>
119 void add(const std::string &k, void (L::*func)(A0, A1, A2))
120 { add(k, new LoaderFunc3<L, A0, A1, A2>(func)); }
122 template<typename L, typename A0, typename A1, typename A2, typename A3>
123 void add(const std::string &k, void (L::*func)(A0, A1, A2, A3))
124 { add(k, new LoaderFunc4<L, A0, A1, A2, A3>(func)); }
126 template<typename L, typename A0, typename A1, typename A2, typename A3, typename A4>
127 void add(const std::string &k, void (L::*func)(A0, A1, A2, A3, A4))
128 { add(k, new LoaderFunc5<L, A0, A1, A2, A3, A4>(func)); }
130 /** Adds a keyword that is loaded into a member of the loaded object. */
131 template<typename L, typename T0>
132 void add(const std::string &k, T0 L::*p0)
133 { add(k, new LoadValue1<L, T0>(p0)); }
135 template<typename L, typename T0, typename T1>
136 void add(const std::string &k, T0 L::*p0, T1 L::*p1)
137 { add(k, new LoadValue2<L, T0, T1>(p0, p1)); }
139 /** Adds a keyword that is recognized but ignored. */
140 void add(const std::string &k)
144 void add(const std::string &, LoaderAction *);
146 LoaderAction *find_action(const ActionKey &) const;
149 /** Returns the source of the statement being processed. This can be used
150 to implement relative paths in include-like statements. Note that the
151 source may not necessarily be a file. */
152 const std::string &get_source() const
155 throw InvalidState("get_source called without current statement");
156 return cur_st->source;
159 virtual void finish() { }
164 Deprecated. See ObjectLoader in objectloader.h.
167 class BasicLoader: public Loader
176 BasicLoader(O &o): obj(o) { }
177 O &get_object() const { return obj; }
182 Deprecated. See CollectionObjectLoader in objectloader.h.
184 template<typename O, typename C>
185 class BasicLoader2: public BasicLoader<O>
188 typedef C Collection;
194 BasicLoader2(O &o, C &c): BasicLoader<O>(o), coll(c) { }
195 C &get_collection() const { return coll; }
200 Loads an object from a file. The object must have a public Loader class.
203 void load(T &obj, const std::string &fn)
206 IO::Buffered buf(in);
208 Parser parser(buf, fn);
209 typename T::Loader loader(obj);
213 template<typename T, typename U>
214 void load(T &obj, const std::string &fn, U &arg)
217 IO::Buffered buf(in);
219 Parser parser(buf, fn);
220 typename T::Loader loader(obj, arg);
224 } // namespace DataFile