00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef TSE3_FILE_XML_H
00018 #define TSE3_FILE_XML_H
00019
00020 #include <iosfwd>
00021 #include <iomanip>
00022 #include <cstddef>
00023 #include <string>
00024 #include <map>
00025 #include <strstream>
00026
00027 #include "tse3/Midi.h"
00028
00029 namespace TSE3
00030 {
00031 class Song;
00032 class Progress;
00033
00034 namespace File
00035 {
00036
00044 struct XmlLoadInfo
00045 {
00052 int PPQN;
00053
00059 Song *song;
00060
00068 int major;
00069
00077 int minor;
00078
00088 bool unknownChunks;
00089
00099 bool unknownData;
00100
00109 size_t noChunks;
00110
00118 Progress *progress;
00119
00132 XmlLoadInfo();
00133 };
00134
00135
00136
00137
00138
00139
00143 class XmlFileWriter
00144 {
00145 public:
00146
00147 XmlFileWriter(std::ostream &out);
00148 ~XmlFileWriter();
00149
00150 void openElement(const std::string &name);
00151 void closeElement();
00152
00153 void element(const std::string &name, const std::string &value);
00154 void element(const std::string &name, const char *value);
00155 void element(const std::string &name, int value);
00156 void element(const std::string &name, unsigned int value);
00157 void element(const std::string &name, bool value);
00158
00159 void comment(const std::string &comment);
00160
00161 class AutoElement
00162 {
00163 public:
00164 AutoElement(TSE3::File::XmlFileWriter &writer,
00165 const std::string &name)
00166 : _writer(writer)
00167 {
00168 _writer.openElement(name);
00169 }
00170 ~AutoElement()
00171 {
00172 _writer.closeElement();
00173 }
00174 private:
00175 TSE3::File::XmlFileWriter &_writer;
00176 };
00177
00178 private:
00179
00180 void indent(std::ostream &out);
00181
00182 std::ostream &out;
00183 int indentLevel;
00184
00185 class XmlFileWriterImpl *pimpl;
00186 };
00187
00191 class XmlFileReader
00192 {
00193 public:
00194
00195 XmlFileReader(std::istream &in);
00196 ~XmlFileReader();
00197
00198 TSE3::Song *load();
00199 private:
00200 std::istream ∈
00201 };
00202
00203
00204
00205
00206
00207
00208 class XmlElementParser;
00209
00210 class XmlBlockParser
00211 {
00212 public:
00213 typedef void (block_handler_t)();
00214
00215 XmlBlockParser();
00216
00217 void add(const std::string &tag, XmlBlockParser &handler);
00218 void add(const std::string &tag, XmlElementParser &handler);
00219 void add(XmlElementParser &handler);
00220
00221 void parse(std::istream &in, const std::string &tag,
00222 XmlLoadInfo &info);
00223
00224 private:
00225
00226 void skipBlock(std::istream &in);
00227
00228 std::map<std::string, XmlElementParser*> elements;
00229 std::map<std::string, XmlBlockParser*> blocks;
00230 XmlElementParser *catchAll;
00231 };
00232
00233
00234 class XmlElementParser
00235 {
00236 public:
00237
00238 XmlElementParser() {}
00239 virtual ~XmlElementParser() = 0;
00240
00248 virtual void parse(const std::string &data) = 0;
00249
00250 private:
00251
00252 XmlElementParser &operator=(const XmlElementParser &);
00253 XmlElementParser(const XmlElementParser &);
00254 };
00255
00268 template<class T, class reason>
00269 class XmlElementParser_ReasonOnOff : public XmlElementParser
00270 {
00271 public:
00272 typedef void (T::*fn_t)(reason, bool);
00273 XmlElementParser_ReasonOnOff(T *obj, fn_t mfun, reason r)
00274 : obj(obj), r(r) , mfun(mfun){}
00278 void parse(const std::string &data)
00279 {
00280 (obj->*mfun)(r, (data == "On" || data == "Yes"));
00281 }
00282 private:
00283 T *obj;
00284 reason r;
00285 fn_t mfun;
00286 };
00287
00300 template <class T>
00301 class XmlElementParser_Number : public XmlElementParser
00302 {
00303 public:
00304 typedef void (T::*fn_t)(int);
00305 XmlElementParser_Number(T *obj, fn_t mfun)
00306 : obj(obj), mfun(mfun) {}
00310 void parse(const std::string &data)
00311 {
00312 int i;
00313 std::istrstream si(data.c_str());
00314 si >> i;
00315 (obj->*mfun)(i);
00316 }
00317 private:
00318 T *obj;
00319 fn_t mfun;
00320 };
00321
00336 template <class T>
00337 class XmlElementParser_Clock : public XmlElementParser
00338 {
00339 public:
00340 typedef void (T::*fn_t)(Clock);
00341 XmlElementParser_Clock(T *obj, fn_t mfun)
00342 : obj(obj), mfun(mfun) {}
00346 void parse(const std::string &data)
00347 {
00348 int i;
00349 std::istrstream si(data.c_str());
00350 si >> i;
00351 (obj->*mfun)(i);
00352 }
00353 private:
00354 T *obj;
00355 fn_t mfun;
00356 };
00357
00369 template <class T>
00370 class XmlElementParser_String : public XmlElementParser
00371 {
00372 public:
00373 typedef void (T::*fn_t)(const std::string &);
00374 XmlElementParser_String(T *obj, fn_t mfun)
00375 : obj(obj), mfun(mfun) {}
00379 void parse(const std::string &data)
00380 {
00381 (obj->*mfun)(data);
00382 }
00383 private:
00384 T *obj;
00385 fn_t mfun;
00386 };
00387 }
00388 }
00389
00390 #endif