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.
50 void load(const Statement &st);
54 Loads statements from a parser.
60 Loader(): cur_st(0) { }
63 Adds a keyword that is loaded with a zero-argument function.
66 void add(const std::string &k, void (L::*func)())
67 { add(k, new LoaderFunc0<L>(func)); }
69 template<typename L, typename A0>
70 void add(const std::string &k, void (L::*func)(A0))
71 { add(k, new LoaderFunc1<L, A0>(func)); }
73 template<typename L, typename A0, typename A1>
74 void add(const std::string &k, void (L::*func)(A0, A1))
75 { add(k, new LoaderFunc2<L, A0, A1>(func)); }
77 template<typename L, typename A0, typename A1, typename A2>
78 void add(const std::string &k, void (L::*func)(A0, A1, A2))
79 { add(k, new LoaderFunc3<L, A0, A1, A2>(func)); }
81 template<typename L, typename A0, typename A1, typename A2, typename A3>
82 void add(const std::string &k, void (L::*func)(A0, A1, A2, A3))
83 { add(k, new LoaderFunc4<L, A0, A1, A2, A3>(func)); }
85 template<typename L, typename A0, typename A1, typename A2, typename A3, typename A4>
86 void add(const std::string &k, void (L::*func)(A0, A1, A2, A3, A4))
87 { add(k, new LoaderFunc5<L, A0, A1, A2, A3, A4>(func)); }
90 Adds a keyword that is loaded into a variable of the loaded object.
92 template<typename L, typename T0>
93 void add(const std::string &k, T0 L::*p0)
94 { add(k, new LoadValue1<L, T0>(p0)); }
96 template<typename L, typename T0, typename T1>
97 void add(const std::string &k, T0 L::*p0, T1 L::*p1)
98 { add(k, new LoadValue2<L, T0, T1>(p0, p1)); }
101 Adds a keyword that is recognized but ignored.
103 void add(const std::string &k)
107 Loads a sub-object from the statement being processed. The Loader class of
108 the sub-object is automatically used.
113 typename S::Loader ldr(s);
118 Loads a sub-object from the statement being processed with an extra parameter
119 for the Loader. The Loader class of the sub-object is automatically used.
121 template<typename S, typename T>
122 void load_sub(S &s, T &p)
124 typename S::Loader ldr(s, p);
129 Processes the current statement's substatements with another Loader.
131 void load_sub_with(Loader &);
134 Returns the source of the statement being processed. This can be used to
135 implement relative paths in include-like statements. Note that the source
136 may not necessarily be a file.
138 const std::string &get_source() const
141 throw InvalidState("get_source called without current statement");
142 return cur_st->source;
145 virtual void finish() { }
147 typedef std::map<std::string, LoaderAction *> ActionMap;
150 const Statement *cur_st;
152 void add(const std::string &, LoaderAction *);
153 void load_statement(const Statement &st);
158 Provides the basic functionality of an object loader. Deriving from this
159 allows loading values directly into member variables of the objects.
162 class BasicLoader: public Loader
171 BasicLoader(O &o): obj(o) { }
172 O &get_object() const { return obj; }
177 Provides functionality for loading objects with a Collection. Deriving from
178 this allows loading pointers to objects in the collection automatically.
180 template<typename O, typename C>
181 class BasicLoader2: public BasicLoader<O>
184 typedef C Collection;
190 BasicLoader2(O &o, C &c): BasicLoader<O>(o), coll(c) { }
191 C &get_collection() const { return coll; }
196 Loads an object from a file. The object must have a public Loader class.
199 void load(T &obj, const std::string &fn)
202 IO::Buffered buf(in);
204 Parser parser(buf, fn);
205 typename T::Loader loader(obj);
209 template<typename T, typename U>
210 void load(T &obj, const std::string &fn, U &arg)
213 IO::Buffered buf(in);
215 Parser parser(buf, fn);
216 typename T::Loader loader(obj, arg);
220 } // namespace DataFile