ibus-qt
1.3.1
|
00001 #ifndef __Q_IBUS_SERIALIZABLE_H_ 00002 #define __Q_IBUS_SERIALIZABLE_H_ 00003 00004 #include <QDebug> 00005 #include "qibusobject.h" 00006 #include <QDBusArgument> 00007 #include <QDBusVariant> 00008 #include <QHash> 00009 #include <QMap> 00010 00011 #define INIT_PRIO_HIGH __attribute__((init_priority(1000))) 00012 // #define INIT_PRIO_LOW __attribute__((init_priority(2000))) 00013 #define INIT_PRIO_LOW 00014 00015 #define IBUS_SERIALIZABLE \ 00016 public: \ 00017 static Serializable *newInstance (void); \ 00018 static MetaTypeInfo staticMetaTypeInfo; \ 00019 virtual const MetaTypeInfo *metaTypeInfo (void) const; 00020 00021 #define IBUS_DECLARE_SERIALIZABLE(classname, name) \ 00022 Serializable * \ 00023 classname::newInstance (void) \ 00024 { \ 00025 return (Serializable *) new classname (); \ 00026 } \ 00027 const Serializable::MetaTypeInfo * \ 00028 classname::metaTypeInfo (void) const \ 00029 { \ 00030 return & (classname::staticMetaTypeInfo); \ 00031 } \ 00032 Serializable::MetaTypeInfo \ 00033 classname::staticMetaTypeInfo INIT_PRIO_LOW (QString(#name), classname::newInstance); 00034 00035 namespace IBus { 00036 00037 class Serializable; 00038 typedef Pointer<Serializable> SerializablePointer; 00039 00040 class Serializable : public Object 00041 { 00042 Q_OBJECT; 00043 00044 template<typename T> friend QDBusVariant & qDBusVariantFromSerializable (const Pointer<T> &p, QDBusVariant & dbus_variant); 00045 template<typename T> friend QDBusVariant qDBusVariantFromSerializable (const Pointer<T> &p); 00046 template<typename T> friend Pointer<T> qDBusVariantToSerializable (const QDBusVariant &variant); 00047 00048 typedef Serializable * (NewInstanceFunc) (void); 00049 00050 protected: 00051 class MetaTypeInfo 00052 { 00053 public: 00054 MetaTypeInfo(const QString &name, NewInstanceFunc _new) : m_className (name) { 00055 Serializable::registerObject (m_className, _new); 00056 } 00057 ~MetaTypeInfo (void) { 00058 Serializable::unregisterObject (m_className); 00059 } 00060 const QString &className (void) const { 00061 return m_className; 00062 } 00063 private: 00064 QString m_className; 00065 }; 00066 00067 public: 00068 Serializable () {} 00069 void setAttachment (const QString &key, const SerializablePointer &value); 00070 SerializablePointer getAttachment (const QString &key) const; 00071 SerializablePointer removeAttachment (const QString &key); 00072 00073 protected: 00074 virtual bool serialize (QDBusArgument &argument); 00075 virtual bool deserialize (const QDBusArgument &argument); 00076 00077 private: 00078 QMap <QString, SerializablePointer> m_attachments; 00079 00080 /* static */ 00081 protected: 00082 static void registerObject (const QString &name, NewInstanceFunc _new); 00083 static void unregisterObject (const QString &name); 00084 00085 private: 00086 static SerializablePointer createInstance (const QString &name); 00087 static QHash<QString, NewInstanceFunc *> type_table; 00088 00089 IBUS_SERIALIZABLE 00090 }; 00091 00092 template<typename T> 00093 QVariant & 00094 qVariantFromSerializable (const Pointer<T> &p, QVariant & variant = QVariant ()) 00095 { 00096 QDBusArgument argument; 00097 00098 argument.beginStructure (); 00099 argument << p->metaTypeInfo ()->className (); 00100 p->serialize (argument); 00101 argument.endStructure (); 00102 00103 variant.setValue (argument); 00104 return variant; 00105 } 00106 00107 template<typename T> 00108 QDBusVariant & 00109 qDBusVariantFromSerializable (const Pointer<T> &p, QDBusVariant &dbus_variant) 00110 { 00111 QVariant variant; 00112 QDBusArgument argument; 00113 00114 argument.beginStructure (); 00115 argument << p->metaTypeInfo ()->className (); 00116 p->serialize (argument); 00117 argument.endStructure (); 00118 variant.setValue (argument); 00119 dbus_variant.setVariant (variant); 00120 00121 return dbus_variant; 00122 } 00123 00124 template<typename T> 00125 QDBusVariant 00126 qDBusVariantFromSerializable (const Pointer<T> &p) 00127 { 00128 QDBusVariant variant; 00129 return qDBusVariantFromSerializable (p, variant); 00130 } 00131 00132 template<typename T> 00133 Pointer<T> 00134 qDBusVariantToSerializable (const QDBusVariant &variant) 00135 { 00136 00137 Pointer<T> p; 00138 QString name; 00139 00140 const QDBusArgument argument = variant.variant().value<QDBusArgument> (); 00141 00142 if (argument.currentType () != QDBusArgument::StructureType) { 00143 return p; 00144 } 00145 00146 argument.beginStructure (); 00147 argument >> name; 00148 p = Serializable::createInstance (name); 00149 if (!p.isNull () && !p->deserialize (argument)) { 00150 p = NULL; 00151 } 00152 argument.endStructure (); 00153 00154 return p; 00155 } 00156 00157 template<typename T> 00158 QDBusArgument& operator<< (QDBusArgument& argument, const Pointer<T> &p) 00159 { 00160 QDBusVariant variant; 00161 argument << qDBusVariantFromSerializable<T> (p, variant); 00162 return argument; 00163 } 00164 00165 template<typename T> 00166 const QDBusArgument& operator>> (const QDBusArgument& argument, Pointer<T> &p) 00167 { 00168 Q_ASSERT ((argument.currentType () == QDBusArgument::VariantType)); 00169 00170 QDBusVariant variant; 00171 argument >> variant; 00172 00173 p = qDBusVariantToSerializable<T> (variant); 00174 00175 return argument; 00176 } 00177 00178 }; 00179 00180 Q_DECLARE_METATYPE (IBus::SerializablePointer); 00181 00182 #endif