#pragma once #include #include #include #include "ZxDynamic.h" #include "ZxXpf.h" class ZxXpfNode; class ZxXpfDoc; // 序列化器 class I_BASE_EXPORT ZxSerializer { public: enum Flags { flagTemplate = 0x01, // 模版 _reserve_1 = 0x02, _reserve_2 = 0x04, _reserve_3 = 0x08 }; ZxSerializer(ZxXpfDoc* p, bool write); // 把对象加载序列化器中, 并返回对象的id unsigned int addObject(IxDynObj* p); // 获取对象的id. // 如果对象未被序列化, 则id是不确定的, 此函数将返回0 unsigned int getObjectId(IxDynObj* p); unsigned int getObjectIndex(IxDynObj* p); // 获取对象指针 IxDynObj* getObjectById(unsigned int id); IxDynObj* getObjectByIndex(unsigned int index); // 保存整棵树 void save(const IxDynObj* root); // 返回整棵树 IxDynObj* load(); // 获取当前Xpf节点指针 ZxXpfNode* getXpfNode(); // 获取当前Xpf节点指针 ZxXpfNode* node(); // 节点指针压栈进入指定子节点 ZxXpfNode* push(const QString& sName); // 节点指针压栈进入指定节点 ZxXpfNode* push(ZxXpfNode* pChildNode); // 节点指针压栈进入匿名节点 ZxXpfNode* push(); // 节点指针弹栈退出到父节点 ZxXpfNode* pop(); // 保存Variant的数据 void setAttribute(const QString& key, const QVariant& v); // 以Variant的方式读取指定数据 const QVariant& getAttribute(const QString& key); // 保存对象指针 template void write(QString key, T* p) { Q_ASSERT_X(p==0 || dynamic_cast(p) != 0, __FUNCTION__, "Pointer is not IxDynObj type. "); Q_ASSERT(m_bWrite); unsigned int id = addObject(p); setAttribute(key, id); } // 读取对象指针 template void read(QString key, T*& p) { Q_ASSERT(!m_bWrite); unsigned int id = getAttribute(key).toUInt(); delete p; p = dynamic_cast(getObjectById(id)); Q_ASSERT_X(p==0 || dynamic_cast(p) != 0, __FUNCTION__, "Pointer is not IxDynObj type. "); } // 保存普通变量 // @note 枚举变量请用 write() template void write(QString key, const T& v) { Q_ASSERT(m_bWrite); setAttribute(key, QVariant::fromValue(v)); } // 读取普通变量 // @note 枚举变量请用 read() template void read(QString key, T& v) { Q_ASSERT(!m_bWrite); const QVariant& v0 = getAttribute(key); if (v0.isValid()) //added 20171129 zx v = v0.value(); } // 把T1类型的变量转换为T0类型保存 // @code // ser->write(m_lineStyle) // @endcode template void write(QString key, const T1& v) { Q_ASSERT(m_bWrite); setAttribute(key, QVariant::fromValue((T0)v)); } // 把变量作为T0类型读取, 再转换为T1返回 // @code // ser->read(m_lineStyle) // @endcode template void read(QString key, T1& v) { Q_ASSERT(!m_bWrite); const QVariant& v0 = getAttribute(key); v = (T1)v0.value(); } // 以二进制块(QByteArray)方式保存数组 template void writeBin(QString key, const QVector& vec) { QByteArray buf((const char*)vec.data(), vec.size()* sizeof(T)); write(key, buf); } // 以二进制块(QByteArray)方式读取数组 template void readBin(QString key, QVector& vec) { QByteArray buf; read(key, buf); Q_ASSERT(buf.size() % sizeof(T) == 0); vec.resize(buf.size() / sizeof(T)); memcpy(vec.data(), buf.data(), buf.size()); } // 以二进制块(QByteArray)方式保存列表 template void writeBin(QString key, const QList& list) { const int count = list.size(); const int bytes = count* sizeof(T); QByteArray buf; buf.resize(bytes); T* p = (T*) buf.data(); for (auto it = list.begin(); it != list.end(); ++it, ++p) { *p = *it; } write(key, buf); } // 以二进制块(QByteArray)方式读取列表 template void readBin(QString key, QList& list) { QByteArray buf; read(key, buf); Q_ASSERT(buf.size() % sizeof(T) == 0); list.clear(); const T* p0 = (const T*) buf.data(); auto p1 = p0 + buf.size() / sizeof(T); for (auto p = p0; p < p1; p++) { list.append(*p); } } // 保存对象指针数组 template void write(QString key, const QVector& vec) { Q_ASSERT(m_bWrite); if (!vec.isEmpty()) { push(key); int n = vec.count(); for (int i=0; iaddUnnamedChild(id); } pop(); } } // 读取对象指针数组 template void read(QString key, QVector& vec) { Q_ASSERT(!m_bWrite); vec.clear(); ZxXpfNode* node = m_pNode->findChild(key, false); if (node) { const QVector& nodes = node->getChildren(); int n = nodes.count(); vec.reserve(n); for (int i=0; igetData().toUInt(); T* p = dynamic_cast(getObjectById(id)); vec.push_back(p); } } } // 保存对象指针列表 template void write(QString key, const QList& vec) { Q_ASSERT(m_bWrite); if (!vec.isEmpty()) { push(key); int n = vec.count(); for (int i=0; iaddUnnamedChild(id); } pop(); } } // 读取对象指针列表 template void read(QString key, QList& vec) { Q_ASSERT(!m_bWrite); vec.clear(); ZxXpfNode* node = m_pNode->findChild(key, false); if (node) { const QVector& nodes = node->getChildren(); int n = nodes.count(); vec.reserve(n); for (int i=0; igetData().toUInt(); T* p = dynamic_cast(getObjectById(id)); vec.push_back(p); } } } // 保存普通非动态对象数组(例如QVector) template void write(QString key, const QVector& vec) { Q_ASSERT(m_bWrite); if (!vec.isEmpty()) { push(key); int n = vec.count(); for (int i=0; isetData(vec[i]); m_pNode->addChild(p); } pop(); } } // 读取普通非动态对象数组(例如QVector) template void read(QString key, QVector& vec) { Q_ASSERT(!m_bWrite); vec.clear(); ZxXpfNode* node = m_pNode->findChild(key, false); if (node) { const QVector& nodes = node->getChildren(); int n = nodes.count(); vec.reserve(n); for (int i=0; igetData().value() ); } } } // 保存普通非动态对象列表(例如QList) template void write(QString key, const QList& vec) { Q_ASSERT(m_bWrite); if (!vec.isEmpty()) { push(key); int n = vec.count(); for (int i=0; isetData(vec[i]); m_pNode->addChild(p); } pop(); } } // 读取普通非动态对象列表(例如QList) template void read(QString key, QList& vec) { Q_ASSERT(!m_bWrite); vec.clear(); ZxXpfNode* node = m_pNode->findChild(key, false); if (node) { const QVector& nodes = node->getChildren(); int n = nodes.count(); for (int i=0; igetData().value() ); } } } // ------------------- // 是否模版模式 bool isTemplate() const; // 设置模版模式 void setTemplate(bool b); // Xpf格式版本号 quint32 getXpfVer() const; // 文档类型 QString getDocType() const; void setDocType(const QString& sDocType); // 文档标识 quint32 getDocFlags() const; void setDocFlags(quint32 flags, bool bSet); // 应用层的文件版本号 quint32 getDocVer() const; void setDocVer(quint32 nVersion); // 8位数日期 quint32 getDocDate() const; void setDocDate(quint32 nDate); unsigned int objectIndexToId(unsigned int index) const; unsigned int objectIdToIndex(unsigned int id) const; bool isObjectId(unsigned int n) const; // NULL的id也返回true bool isObjectIndex(unsigned int n) const; // 0 也返回true private: QHash m_hashObjIds; QVector m_vecObjs; ZxXpfDoc* m_pDoc; ZxXpfNode* m_pNode; bool m_bWrite; };