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/file.h>
14 #include "loaderaction.h"
16 #include "statement.h"
22 Base class for data loaders. This class only provides core functionality.
23 You'll almost certainly want to use one of the BasicLoader classes instead.
25 Under normal circumstances, a class capable of being loaded should have a
26 nested typed called Loader which resolves to a descendant of this class. If
27 another structure is used, the loader object must be constructed manually.
29 A loader class should execute one or more calls to the various add() functions
30 to register actions with expected keywords. Currently possible actions are
31 calling a function of the loader, storing values in member variables of an
32 object and ignoring the statement. If a unexpected keyword is encountered, an
33 exception is thrown and the loading is aborted.
35 A sub-object can be loaded with one of the load_sub functions.
37 When loading has finished successfully, the virtual function finish() is
38 called. Any post-processing of the data should be placed here and not in the
41 See also classes BasicLoader and BasicLoader2.
49 std::string signature;
51 ActionKey(const std::string &, const std::string &);
53 bool operator<(const ActionKey &) const;
56 typedef std::map<ActionKey, LoaderAction *> ActionMap;
59 const Statement *cur_st;
62 bool allow_pointer_reload;
69 bool is_pointer_reload_allowed() const { return allow_pointer_reload; }
71 /** Loads statements from a parser. */
75 /** Loads data from a statement. */
76 void load(const Statement &st);
78 /** Processes a single statement */
79 void load_statement(const Statement &st);
82 /** Loads a sub-object from the statement being processed. The Loader class
83 of the sub-object is automatically used. */
87 typename S::Loader ldr(s);
91 /** Loads a sub-object from the statement being processed with an extra
92 parameter for the Loader. The Loader class of the sub-object is
93 automatically used. */
94 template<typename S, typename T>
95 void load_sub(S &s, T &p)
97 typename S::Loader ldr(s, p);
101 /** Processes the current statement's substatements with another Loader. */
102 void load_sub_with(Loader &);
104 /** Adds a keyword that is loaded by calling a function. */
106 void add(const std::string &k, void (L::*func)())
107 { add(k, new LoaderFunc0<L>(func)); }
109 template<typename L, typename A0>
110 void add(const std::string &k, void (L::*func)(A0))
111 { add(k, new LoaderFunc1<L, A0>(func)); }
113 template<typename L, typename A0, typename A1>
114 void add(const std::string &k, void (L::*func)(A0, A1))
115 { add(k, new LoaderFunc2<L, A0, A1>(func)); }
117 template<typename L, typename A0, typename A1, typename A2>
118 void add(const std::string &k, void (L::*func)(A0, A1, A2))
119 { add(k, new LoaderFunc3<L, A0, A1, A2>(func)); }
121 template<typename L, typename A0, typename A1, typename A2, typename A3>
122 void add(const std::string &k, void (L::*func)(A0, A1, A2, A3))
123 { add(k, new LoaderFunc4<L, A0, A1, A2, A3>(func)); }
125 template<typename L, typename A0, typename A1, typename A2, typename A3, typename A4>
126 void add(const std::string &k, void (L::*func)(A0, A1, A2, A3, A4))
127 { add(k, new LoaderFunc5<L, A0, A1, A2, A3, A4>(func)); }
129 /** Adds a keyword that is loaded into a member of the loaded object. */
130 template<typename L, typename T0>
131 void add(const std::string &k, T0 L::*p0)
132 { add(k, new LoadValue1<L, T0>(p0)); }
134 template<typename L, typename T0, typename T1>
135 void add(const std::string &k, T0 L::*p0, T1 L::*p1)
136 { add(k, new LoadValue2<L, T0, T1>(p0, p1)); }
138 /** Adds a keyword that is recognized but ignored. */
139 void add(const std::string &k)
143 void add(const std::string &, LoaderAction *);
145 LoaderAction *find_action(const ActionKey &) const;
148 /** Returns the source of the statement being processed. This can be used
149 to implement relative paths in include-like statements. Note that the
150 source may not necessarily be a file. */
151 const std::string &get_source() const
154 throw InvalidState("get_source called without current statement");
155 return cur_st->source;
158 virtual void finish() { }
163 Deprecated. See ObjectLoader in objectloader.h.
166 class BasicLoader: public Loader
175 BasicLoader(O &o): obj(o) { }
176 O &get_object() const { return obj; }
181 Deprecated. See CollectionObjectLoader in objectloader.h.
183 template<typename O, typename C>
184 class BasicLoader2: public BasicLoader<O>
187 typedef C Collection;
193 BasicLoader2(O &o, C &c): BasicLoader<O>(o), coll(c) { }
194 C &get_collection() const { return coll; }
199 Loads an object from a file. The object must have a public Loader class.
202 void load(T &obj, const std::string &fn)
204 IO::BufferedFile in(fn);
206 Parser parser(in, fn);
207 typename T::Loader loader(obj);
211 template<typename T, typename U>
212 void load(T &obj, const std::string &fn, U &arg)
214 IO::BufferedFile in(fn);
216 Parser parser(in, fn);
217 typename T::Loader loader(obj, arg);
221 } // namespace DataFile