Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members  

Serializer.h

00001 //  Serializer - base class for storing Serializables
00002 //  Copyright (C) 2000-2003 bozo & sgbeal @users.sourceforge.net
00003 //
00004 //  This program is free software; you can redistribute it and/or
00005 //  modify it under the terms of the GNU General Public License
00006 //  as published by the Free Software Foundation; either version 2
00007 //  of the License, or (at your option) any later version.
00008 //
00009 //  This program is distributed in the hope that it will be useful,
00010 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 //  GNU General Public License for more details.
00013 //
00014 //  You should have received a copy of the GNU General Public License
00015 //  along with this program; if not, write to the Free Software
00016 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00017 
00018 #ifndef _FUN_SERIALIZER_H
00019 #define _FUN_SERIALIZER_H
00020 
00021 #include <fun/fun.h>
00022 #include <fun/Serializable.h>
00023 #include <qlist.h>
00024 
00025 class QString;
00026 class QColor;
00027 class QPoint;
00028 class QSize;
00029 
00030 namespace fun {
00031 
00032 //  Remove when you can...
00033 #define SERIALIZER_API_COMPAT 1
00034 
00035 /**
00036 *  Serializer is an abstract base class for objects which can store
00037 *  Serializable objects to files or streams.  Depending on the subclass'
00038 *  implementation, the data may be stored natively, or it may be converted to
00039 *  strings, or stuck in a database, etc.
00040 *
00041 *  Think of a Serializer as taking key/value pairs of data, where the values
00042 *  may be Serializable objects, which implies a tree structure.  Duplicate
00043 *  keys are allowed, but note that the only way to get at the values for
00044 *  duplicate keys in a Deserializer is to use one of the forms of get() which
00045 *  takes a reference to a list of Serializables or QStrings.
00046 *
00047 *  As Serializer is abstract, subclasses must provide implementations for
00048 *  the following methods:
00049 *  - put(const QString &key, const QString &val)
00050 *  - put(const QString &key, const Serializable &val)
00051 *  - setSerializableClass(const char *name)
00052 *  Also, setComment() does nothing in the base class.
00053 */
00054 class Serializer
00055 {
00056     public:
00057     /**
00058     *  Creates an empty Serializer node.
00059     */
00060     Serializer() { }
00061     virtual ~Serializer() { }
00062 
00063     /**
00064     *  Adds a new element containing the given string value.
00065     *  This is one of the methods which subclasses must implement.
00066     */
00067     virtual void put(const QString &key, const QString &val) = 0;
00068 
00069     /**
00070     *  Adds a new element containing the given string value.
00071     *  (this one is because put(key, "bleh") was calling the bool version!)
00072     */
00073     void put(const QString &key, const char *val) { put(key, QString(val)); }
00074 
00075     /**
00076     *  This is just like the string version of put(), except that it
00077     *  converts the given int value to a string.
00078     */
00079     virtual void put(const QString &key, int val);
00080 
00081     /**
00082     *  This is just like the string version of put(), except that it
00083     *  converts the given unsigned int value to a string.
00084     */
00085     virtual void put(const QString &key, unsigned val);
00086 
00087     /**
00088     *  This is just like the string version of put(), except that it
00089     *  converts the given bool value to a string.
00090     */
00091     virtual void put(const QString &key, bool val);
00092 
00093     /**
00094     *  This is just like the string version of put(), except that it
00095     *  converts the given float value to a string.
00096     */
00097     virtual void put(const QString &key, float val);
00098 
00099     /**
00100     *  This is just like the string version of put(), except that it
00101     *  converts the given double value to a string.
00102     */
00103     virtual void put(const QString &key, double val);
00104 
00105     /**
00106     *  This is just like the string version of put(), except that it
00107     *  converts the given QColor value to a string in the format #rrggbb.
00108     */
00109     virtual void put(const QString &key, const QColor &val);
00110 
00111     /**
00112     *  Adds a new element containing the given Serializable value.
00113     *  Passing a NULL Serializable here has the same effect as not
00114     *  calling it at all.
00115     *
00116     *  This is one of the methods which subclasses must implement.
00117     */
00118     virtual void put(const QString &key, const Serializable *val) = 0;
00119 
00120     /**
00121     *  Calls put() for each element in the list.
00122     */
00123     virtual void put(const QString &key, const QPtrList<Serializable> &list);
00124 
00125     /**
00126     *  Calls put() for each element in the list.  To serialize an entire
00127     *  std::vector<Serializable *>, call put(key, vec.begin(), vec.end()).
00128     */
00129     template <class InputIterator>
00130     void put(const QString &key, InputIterator begin, InputIterator end) { while (begin != end) put(key, *begin++); }
00131 
00132     /**
00133     *  Calls put() for each Serializable element in the list.  This is
00134     *  because even if Foo is a subclass of Serializable, QPtrList<Foo>
00135     *  can't be (or isn't being) treated as a QPtrList<Serializable>.
00136     */
00137     template <class SC>
00138     void put(const QString &key, const QPtrList<SC> &list);
00139 
00140     /**
00141     *  Calls put() for each Serializable element in the array of pointers.
00142     *  NULL elements in the list will be ignored... nuts, that means you
00143     *  can't rely on it to deserialize the same way.  OK, how about the
00144     *  behavior is undefined in that case, ha ha.
00145     */
00146     template <class SC>
00147     void put(const QString &key, const SC * const *list, unsigned len);
00148 
00149     /**
00150     *  Calls put() for each element in the list.  Note that in the result
00151     *  there may be no way to tell "null" and "empty" strings apart.
00152     */
00153     virtual void put(const QString &key, const QStringList &list);
00154 
00155     /**
00156     *  Calls put() for each element in the list.  Note that in the result
00157     *  there may be no way to tell "null" and "empty" strings apart.
00158     */
00159     virtual void put(const QString &key, const QString *list, unsigned len);
00160 
00161     /**
00162     *  This is just like the string version of put(), except that it
00163     *  converts the given QPoint value to a string in the format "x,y".
00164     */
00165     virtual void put(const QString &key, const QPoint &val);
00166 
00167     /**
00168     *  This is just like the string version of put(), except that it
00169     *  converts the given QSize value to a string in the format "x,y".
00170     */
00171     virtual void put(const QString &key, const QSize &val);
00172 
00173     /**
00174     *  This sets the name of the Serializable subclass name, so that the same
00175     *  class can be instantiated during deserialization.  Every Serializable's
00176     *  serialize() method should call this with its own class name after
00177     *  calling its superclass' serialize().
00178     *
00179     *  This is one of the methods which subclasses must implement.
00180     */
00181     virtual void setSerializableClass(const char *name) = 0;
00182 
00183     /**
00184     *  Sets an optional comment which will be associated with a child
00185     *  element.  Note that if you have multiple elements with the same
00186     *  key, you're probably only going to have one comment.
00187     *
00188     *  The default base class behavior is to do nothing.
00189     */
00190     virtual void setComment(const QString &key, const QString &comment);
00191 
00192 #if SERIALIZER_API_COMPAT
00193     void putString(const QString &key, const QString &val) { put(key, val); }
00194     void putInt(const QString &key, int val) { put(key, val); }
00195     void putUInt(const QString &key, unsigned val) { put(key, val); }
00196     void putBool(const QString &key, bool val) { put(key, val); }
00197     void putFloat(const QString &key, float val) { put(key, val); }
00198     void putDouble(const QString &key, double val) { put(key, val); }
00199     void putColor(const QString &key, const QColor &val) { put(key, val); }
00200     void putSerializable(const QString &key, const Serializable &val) { put(key, &val); }
00201     void putSerializables(const QString &key, const QPtrList<Serializable> &list) { put(key, list); }
00202     void putStrings(const QString &key, const QStringList &list) { put(key, list); }
00203     void putPoint( const QString &key, const QPoint &val ) { put(key, val); }
00204     void putSize( const QString &key, const QSize &val ) { put(key, val); }
00205 #endif
00206 };
00207 
00208 template <class SC>
00209 void
00210 Serializer::put(const QString &key, const QPtrList<SC> &list)
00211 {
00212     for(QPtrListIterator<SC> it(list); it.current(); ++it)
00213     {
00214         Serializable *sp = dynamic_cast<Serializable *>(it.current());
00215         if (sp) put(key, sp);
00216         else
00217         {
00218             NOT_DONE("need to warn that non-Serializable object is being ignored?");
00219         }
00220     }
00221 }
00222 
00223 template <class SC>
00224 void
00225 Serializer::put(const QString &key, const SC * const *list, unsigned len)
00226 {
00227     for(unsigned i = 0; i < len; ++i)
00228     {
00229         if (list[i] == NULL) continue;
00230         const Serializable *sp = dynamic_cast<const Serializable *>(list[i]);
00231         if (sp) put(key, sp);
00232         else
00233         {
00234             NOT_DONE("need to warn that non-Serializable object is being ignored?");
00235         }
00236     }
00237 }
00238 
00239 }  //  namespace fun
00240 
00241 #endif  //  _FUN_SERIALIZER_H

Generated on Mon Aug 11 14:06:55 2003 for libfunutil by doxygen1.2.18