mirror of
https://gitee.com/drabel/LibQQt.git
synced 2025-01-04 10:18:44 +08:00
数据持久化类,使用Marker强制写
This commit is contained in:
parent
ff1598150c
commit
c7a3ec35f6
@ -1,420 +1,2 @@
|
||||
#include "qqtiniparser.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include "inifile.h"
|
||||
#include "qqtdictionary.h"
|
||||
|
||||
QByteArray toIni ( const QQtDictionary& dict )
|
||||
{
|
||||
const QQtDictionary& node = dict;
|
||||
|
||||
inifile::IniFile p0;
|
||||
switch ( dict.getType() )
|
||||
{
|
||||
case QQtDictionary::DictValue:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case QQtDictionary::DictList:
|
||||
{
|
||||
//"name":[a, b, ...]
|
||||
for ( int i = 0; i < node.getList().size(); i++ )
|
||||
{
|
||||
#if 0
|
||||
QList<QQtDictionary>& l = node.getList();
|
||||
if ( l[i].getType() == QQtDictionary::DictValue )
|
||||
{
|
||||
QString qkey = QString::number ( i );
|
||||
string key = qkey.toStdString();
|
||||
string value = l[i].getValue().toString().toStdString();
|
||||
string comment = node["__comments__"][""][qkey]["#comment"].getValue().toString().toStdString();
|
||||
string right_comment = node["__comments__"][""][qkey]["#right_comment"].getValue().toString().toStdString();
|
||||
p0.SetStringValue ( "", key, value );
|
||||
p0.SetComment ( "", key, comment );
|
||||
p0.SetRightComment ( "", key, right_comment );
|
||||
}
|
||||
#else
|
||||
const QString& sec = QString::number ( i );
|
||||
string stdsec = sec.toStdString();
|
||||
|
||||
QList<QQtDictionary>& l = node.getList();
|
||||
const QQtDictionary& srcvalue = l[i];
|
||||
|
||||
p0.AddSection ( stdsec );
|
||||
|
||||
string comment = node["__comments__"][sec]["#comment"].getValue().toString().toStdString();
|
||||
string right_comment = node["__comments__"][sec]["#right_comment"].getValue().toString().toStdString();
|
||||
p0.SetComment ( stdsec, "", comment );
|
||||
p0.SetRightComment ( stdsec, "", right_comment );
|
||||
|
||||
if ( srcvalue.getType() == QQtDictionary::DictList )
|
||||
{
|
||||
for ( int i = 0; i < srcvalue.getList().size(); i++ )
|
||||
{
|
||||
QList<QQtDictionary>& l = srcvalue.getList();
|
||||
if ( l[i].getType() == QQtDictionary::DictValue )
|
||||
{
|
||||
QString qkey = QString::number ( i );
|
||||
string key = qkey.toStdString();
|
||||
string value = l[i].getValue().toString().toStdString();
|
||||
string comment = node["__comments__"][sec][qkey]["#comment"].getValue().toString().toStdString();
|
||||
string right_comment = node["__comments__"][sec][qkey]["#right_comment"].getValue().toString().toStdString();
|
||||
p0.SetStringValue ( stdsec, key, value );
|
||||
p0.SetComment ( stdsec, key, comment );
|
||||
p0.SetRightComment ( stdsec, key, right_comment );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( srcvalue.getType() == QQtDictionary::DictMap )
|
||||
{
|
||||
for ( QMap<QString, QQtDictionary>::Iterator itor2 = srcvalue.getMap().begin();
|
||||
itor2 != srcvalue.getMap().end(); itor2++ )
|
||||
{
|
||||
//QMap<QString, QQtDictionary>& m = node.getMap();
|
||||
const QString& qkey2 = itor2.key();
|
||||
string stdkey2 = qkey2.toStdString();
|
||||
const QQtDictionary& srcvalue2 = itor2.value();
|
||||
if ( srcvalue2.getType() == QQtDictionary::DictValue )
|
||||
{
|
||||
string value = srcvalue2.getValue().toString().toStdString();
|
||||
string comment = node["__comments__"][sec][qkey2]["#comment"].getValue().toString().toStdString();
|
||||
string right_comment = node["__comments__"][sec][qkey2]["#right_comment"].getValue().toString().toStdString();
|
||||
p0.SetStringValue ( stdsec, stdkey2, value );
|
||||
p0.SetComment ( stdsec, stdkey2, comment );
|
||||
p0.SetRightComment ( stdsec, stdkey2, right_comment );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QQtDictionary::DictMap:
|
||||
{
|
||||
//"name": {"a":"b", "a2":"b2", "a3":["b31", "b32"], "a4":{"a41":"b41", "a42":"b42"}, ...}
|
||||
for ( QMap<QString, QQtDictionary>::Iterator itor = node.getMap().begin();
|
||||
itor != node.getMap().end(); itor++ )
|
||||
{
|
||||
//QMap<QString, QQtDictionary>& m = node.getMap();
|
||||
const QString& sec = itor.key();
|
||||
string stdsec = sec.toStdString();
|
||||
const QQtDictionary& srcvalue = itor.value();
|
||||
|
||||
if ( sec == "__comments__" )
|
||||
continue;
|
||||
|
||||
p0.AddSection ( stdsec );
|
||||
|
||||
string comment = node["__comments__"][sec]["#comment"].getValue().toString().toStdString();
|
||||
string right_comment = node["__comments__"][sec]["#right_comment"].getValue().toString().toStdString();
|
||||
//qDebug() << QString::fromStdString ( comment );
|
||||
//qDebug() << QString::fromStdString ( right_comment );
|
||||
int ret;
|
||||
ret = p0.SetComment ( stdsec, "", comment );
|
||||
//qDebug() << ret;
|
||||
ret = p0.SetRightComment ( stdsec, "", right_comment );
|
||||
//qDebug() << ret;
|
||||
|
||||
if ( srcvalue.getType() == QQtDictionary::DictList )
|
||||
{
|
||||
for ( int i = 0; i < srcvalue.getList().size(); i++ )
|
||||
{
|
||||
QList<QQtDictionary>& l = srcvalue.getList();
|
||||
if ( l[i].getType() == QQtDictionary::DictValue )
|
||||
{
|
||||
QString qkey = QString::number ( i );
|
||||
string key = qkey.toStdString();
|
||||
string value = l[i].getValue().toString().toStdString();
|
||||
string comment = node["__comments__"][sec][qkey]["#comment"].getValue().toString().toStdString();
|
||||
string right_comment = node["__comments__"][sec][qkey]["#right_comment"].getValue().toString().toStdString();
|
||||
p0.SetStringValue ( stdsec, key, value );
|
||||
p0.SetComment ( stdsec, key, comment );
|
||||
p0.SetRightComment ( stdsec, key, right_comment );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( srcvalue.getType() == QQtDictionary::DictMap )
|
||||
{
|
||||
for ( QMap<QString, QQtDictionary>::Iterator itor2 = srcvalue.getMap().begin();
|
||||
itor2 != srcvalue.getMap().end(); itor2++ )
|
||||
{
|
||||
//QMap<QString, QQtDictionary>& m = node.getMap();
|
||||
const QString& qkey2 = itor2.key();
|
||||
string stdkey2 = qkey2.toStdString();
|
||||
const QQtDictionary& srcvalue2 = itor2.value();
|
||||
if ( srcvalue2.getType() == QQtDictionary::DictValue )
|
||||
{
|
||||
string value = srcvalue2.getValue().toString().toStdString();
|
||||
string comment = node["__comments__"][sec][qkey2]["#comment"].getValue().toString().toStdString();
|
||||
string right_comment = node["__comments__"][sec][qkey2]["#right_comment"].getValue().toString().toStdString();
|
||||
p0.SetStringValue ( stdsec, stdkey2, value );
|
||||
p0.SetComment ( stdsec, stdkey2, comment );
|
||||
p0.SetRightComment ( stdsec, stdkey2, right_comment );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QQtDictionary::DictMax:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
int ret;
|
||||
|
||||
std::string buffer;
|
||||
ret = p0.SaveToContent ( buffer );
|
||||
//qDebug() << ret;
|
||||
|
||||
QByteArray bytes = QByteArray::fromStdString ( buffer );
|
||||
//qDebug() << qPrintable ( bytes );
|
||||
|
||||
//不返回会崩溃
|
||||
return bytes;
|
||||
}
|
||||
|
||||
void fromIni ( const QByteArray& bytes, QQtDictionary& dict )
|
||||
{
|
||||
inifile::IniFile p0;
|
||||
int ret;
|
||||
ret = p0.LoadFromContent ( bytes.toStdString() );
|
||||
|
||||
//qDebug() << ret;
|
||||
vector<string> secs;
|
||||
ret = p0.GetSections ( &secs );
|
||||
for ( vector<string>::iterator itor = secs.begin();
|
||||
itor != secs.end(); itor++ )
|
||||
{
|
||||
string& secName = *itor;
|
||||
inifile::IniSection* sec = p0.getSection ( secName );
|
||||
//sec name
|
||||
string name = sec->name; QString qname = QString::fromStdString ( name );
|
||||
//sec comment
|
||||
string comment = sec->comment; QString qcomment = QString::fromStdString ( comment );
|
||||
//sec right_comment
|
||||
string right_comment = sec->rightComment; QString qright_comment = QString::fromStdString ( right_comment );
|
||||
|
||||
dict["__comments__"][qname]["#comment"] = qcomment;
|
||||
dict["__comments__"][qname]["#right_comment"] = qright_comment;
|
||||
|
||||
//sec child
|
||||
for ( inifile::IniSection::IniItem_it it = sec->begin();
|
||||
it != sec->end(); it++ )
|
||||
{
|
||||
inifile::IniItem& item = *it;
|
||||
|
||||
//#comment
|
||||
string comment = item.comment; QString qcomment = QString::fromStdString ( comment );
|
||||
//#right_comment
|
||||
string right_comment = item.rightComment; QString qright_comment = QString::fromStdString ( right_comment );
|
||||
//key
|
||||
string key = item.key; QString qkey = QString::fromStdString ( key );
|
||||
//value
|
||||
string value = item.value; QString qvalue = QString::fromStdString ( value );
|
||||
|
||||
dict["__comments__"][qname][qkey]["#comment"] = qcomment;
|
||||
dict["__comments__"][qname][qkey]["#right_comment"] = qright_comment;
|
||||
dict[qname][qkey] = qvalue;
|
||||
}
|
||||
}
|
||||
|
||||
//qDebug() << qPrintable ( dict.toJson ( QJsonDocument::Indented ) );
|
||||
}
|
||||
|
||||
QByteArray toProperties ( const QQtDictionary& dict )
|
||||
{
|
||||
const QQtDictionary& node = dict;
|
||||
|
||||
inifile::IniFile p0;
|
||||
switch ( dict.getType() )
|
||||
{
|
||||
case QQtDictionary::DictValue:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case QQtDictionary::DictList:
|
||||
{
|
||||
//"name":[a, b, ...]
|
||||
for ( int i = 0; i < node.getList().size(); i++ )
|
||||
{
|
||||
#if 0
|
||||
QList<QQtDictionary>& l = node.getList();
|
||||
if ( l[i].getType() == QQtDictionary::DictValue )
|
||||
{
|
||||
QString qkey = QString::number ( i );
|
||||
string key = qkey.toStdString();
|
||||
string value = l[i].getValue().toString().toStdString();
|
||||
string comment = node["__comments__"][""][qkey]["#comment"].getValue().toString().toStdString();
|
||||
string right_comment = node["__comments__"][""][qkey]["#right_comment"].getValue().toString().toStdString();
|
||||
p0.SetStringValue ( "", key, value );
|
||||
p0.SetComment ( "", key, comment );
|
||||
p0.SetRightComment ( "", key, right_comment );
|
||||
}
|
||||
#elif 0
|
||||
const QString& sec = QString::number ( i );
|
||||
string stdsec = sec.toStdString();
|
||||
|
||||
QList<QQtDictionary>& l = node.getList();
|
||||
const QQtDictionary& srcvalue = l[i];
|
||||
|
||||
p0.AddSection ( stdsec );
|
||||
|
||||
string comment = node["__comments__"][sec]["#comment"].getValue().toString().toStdString();
|
||||
string right_comment = node["__comments__"][sec]["#right_comment"].getValue().toString().toStdString();
|
||||
p0.SetComment ( stdsec, "", comment );
|
||||
p0.SetRightComment ( stdsec, "", right_comment );
|
||||
|
||||
if ( srcvalue.getType() == QQtDictionary::DictList )
|
||||
{
|
||||
for ( int i = 0; i < srcvalue.getList().size(); i++ )
|
||||
{
|
||||
QList<QQtDictionary>& l = srcvalue.getList();
|
||||
if ( l[i].getType() == QQtDictionary::DictValue )
|
||||
{
|
||||
QString qkey = QString::number ( i );
|
||||
string key = qkey.toStdString();
|
||||
string value = l[i].getValue().toString().toStdString();
|
||||
string comment = node["__comments__"][sec][qkey]["#comment"].getValue().toString().toStdString();
|
||||
string right_comment = node["__comments__"][sec][qkey]["#right_comment"].getValue().toString().toStdString();
|
||||
p0.SetStringValue ( stdsec, key, value );
|
||||
p0.SetComment ( stdsec, key, comment );
|
||||
p0.SetRightComment ( stdsec, key, right_comment );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( srcvalue.getType() == QQtDictionary::DictMap )
|
||||
{
|
||||
for ( QMap<QString, QQtDictionary>::Iterator itor2 = srcvalue.getMap().begin();
|
||||
itor2 != srcvalue.getMap().end(); itor2++ )
|
||||
{
|
||||
//QMap<QString, QQtDictionary>& m = node.getMap();
|
||||
const QString& qkey2 = itor2.key();
|
||||
string stdkey2 = qkey2.toStdString();
|
||||
const QQtDictionary& srcvalue2 = itor2.value();
|
||||
if ( srcvalue2.getType() == QQtDictionary::DictValue )
|
||||
{
|
||||
string value = srcvalue2.getValue().toString().toStdString();
|
||||
string comment = node["__comments__"][sec][qkey2]["#comment"].getValue().toString().toStdString();
|
||||
string right_comment = node["__comments__"][sec][qkey2]["#right_comment"].getValue().toString().toStdString();
|
||||
p0.SetStringValue ( stdsec, stdkey2, value );
|
||||
p0.SetComment ( stdsec, stdkey2, comment );
|
||||
p0.SetRightComment ( stdsec, stdkey2, right_comment );
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
const QString& key = QString::number ( i );
|
||||
string stdkey = key.toStdString();
|
||||
QList<QQtDictionary>& l = node.getList();
|
||||
const QQtDictionary& srcvalue = l[i];
|
||||
|
||||
if ( key == "__comments__" )
|
||||
continue;
|
||||
|
||||
if ( srcvalue.getType() != QQtDictionary::DictValue )
|
||||
continue;
|
||||
|
||||
p0.AddSection ( "" );
|
||||
|
||||
string value = srcvalue.getValue().toString().toStdString();
|
||||
string comment = node["__comments__"][key]["#comment"].getValue().toString().toStdString();
|
||||
string right_comment = node["__comments__"][key]["#right_comment"].getValue().toString().toStdString();
|
||||
p0.SetStringValue ( "", stdkey, value );
|
||||
p0.SetComment ( "", stdkey, comment );
|
||||
p0.SetRightComment ( "", stdkey, right_comment );
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QQtDictionary::DictMap:
|
||||
{
|
||||
//"name": {"a":"b", "a2":"b2", "a3":["b31", "b32"], "a4":{"a41":"b41", "a42":"b42"}, ...}
|
||||
for ( QMap<QString, QQtDictionary>::Iterator itor = node.getMap().begin();
|
||||
itor != node.getMap().end(); itor++ )
|
||||
{
|
||||
//QMap<QString, QQtDictionary>& m = node.getMap();
|
||||
const QString& key = itor.key();
|
||||
string stdkey = key.toStdString();
|
||||
const QQtDictionary& srcvalue = itor.value();
|
||||
|
||||
if ( key == "__comments__" )
|
||||
continue;
|
||||
|
||||
if ( srcvalue.getType() != QQtDictionary::DictValue )
|
||||
continue;
|
||||
|
||||
p0.AddSection ( "" );
|
||||
|
||||
string value = srcvalue.getValue().toString().toStdString();
|
||||
string comment = node["__comments__"][key]["#comment"].getValue().toString().toStdString();
|
||||
string right_comment = node["__comments__"][key]["#right_comment"].getValue().toString().toStdString();
|
||||
p0.SetStringValue ( "", stdkey, value );
|
||||
p0.SetComment ( "", stdkey, comment );
|
||||
p0.SetRightComment ( "", stdkey, right_comment );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QQtDictionary::DictMax:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
int ret;
|
||||
|
||||
std::string buffer;
|
||||
ret = p0.SaveToContent ( buffer );
|
||||
//qDebug() << ret;
|
||||
|
||||
QByteArray bytes = QByteArray::fromStdString ( buffer );
|
||||
//qDebug() << qPrintable ( bytes );
|
||||
|
||||
//不返回会崩溃
|
||||
return bytes;
|
||||
}
|
||||
|
||||
void fromProperties ( const QByteArray& bytes, QQtDictionary& dict )
|
||||
{
|
||||
inifile::IniFile p0;
|
||||
int ret;
|
||||
ret = p0.LoadFromContent ( bytes.toStdString() );
|
||||
|
||||
//qDebug() << ret;
|
||||
vector<string> secs;
|
||||
ret = p0.GetSections ( &secs );
|
||||
for ( vector<string>::iterator itor = secs.begin();
|
||||
itor != secs.end(); itor++ )
|
||||
{
|
||||
string& secName = *itor;
|
||||
if ( secName != "" )
|
||||
continue;
|
||||
|
||||
inifile::IniSection* sec = p0.getSection ( secName );
|
||||
//sec child
|
||||
for ( inifile::IniSection::IniItem_it it = sec->begin();
|
||||
it != sec->end(); it++ )
|
||||
{
|
||||
inifile::IniItem& item = *it;
|
||||
|
||||
//#comment
|
||||
string comment = item.comment; QString qcomment = QString::fromStdString ( comment );
|
||||
//#right_comment
|
||||
string right_comment = item.rightComment; QString qright_comment = QString::fromStdString ( right_comment );
|
||||
//key
|
||||
string key = item.key; QString qkey = QString::fromStdString ( key );
|
||||
//value
|
||||
string value = item.value; QString qvalue = QString::fromStdString ( value );
|
||||
|
||||
dict["__comments__"][qkey]["#comment"] = qcomment;
|
||||
dict["__comments__"][qkey]["#right_comment"] = qright_comment;
|
||||
dict[qkey] = qvalue;
|
||||
}
|
||||
}
|
||||
|
||||
//qDebug() << qPrintable ( dict.toJson ( QJsonDocument::Indented ) );
|
||||
}
|
||||
|
@ -1,14 +1,6 @@
|
||||
#ifndef QQTINIPARSER_H
|
||||
#define QQTINIPARSER_H
|
||||
|
||||
#include "qqtdictionary.h"
|
||||
|
||||
#include <qqt-local.h>
|
||||
|
||||
QQTSHARED_EXPORT QByteArray toIni ( const QQtDictionary& dict );
|
||||
QQTSHARED_EXPORT void fromIni ( const QByteArray& bytes, QQtDictionary& dict );
|
||||
|
||||
QQTSHARED_EXPORT QByteArray toProperties ( const QQtDictionary& dict );
|
||||
QQTSHARED_EXPORT void fromProperties ( const QByteArray& bytes, QQtDictionary& dict );
|
||||
#include "inifile.h"
|
||||
|
||||
#endif // QQTINIPARSER_H
|
||||
|
@ -24,6 +24,8 @@ QQtDataPersistence::DataFormat QQtDataPersistence::dataFormat() const { return m
|
||||
void QQtDataPersistence::setDataFile ( const QString& fileName )
|
||||
{
|
||||
mFileName = fileName;
|
||||
if ( mFileName.isEmpty() )
|
||||
return;
|
||||
parseContentToDictionary();
|
||||
}
|
||||
|
||||
@ -31,7 +33,8 @@ QString QQtDataPersistence::dataFile() const { return mFileName; }
|
||||
|
||||
void QQtDataPersistence::prepareDataPersistence()
|
||||
{
|
||||
parseContentToDictionary();
|
||||
if ( mFileName.isEmpty() )
|
||||
return;
|
||||
mTimer->start();
|
||||
}
|
||||
|
||||
@ -58,56 +61,26 @@ void QQtDataPersistence::setTimerInterval ( int millSecond ) { mTimerInterval =
|
||||
|
||||
void QQtDataPersistence::slotTimeOut()
|
||||
{
|
||||
QByteArray bytes;
|
||||
packDictionaryToContent ( bytes );
|
||||
|
||||
//如果在字典的值不同的时候才存储,其他人对文件的修改将无法体现在字典里。
|
||||
//非独占式,不读文件,减少了写次数。
|
||||
/*减少写文件;fix:文件相同时,使用marker强制写*/
|
||||
static QQtDictionary staticDict;
|
||||
if ( staticDict == mDict )
|
||||
{
|
||||
//qDebug() << "字典相同,不写。";
|
||||
//return;
|
||||
|
||||
//如果在字典的值不同于文件里的值得时候存储,可以减少写文件次数。
|
||||
//独占式,每次读文件,减少了写次数。
|
||||
QByteArray bytes1;
|
||||
readFile ( bytes1 );
|
||||
if ( bytes1 == bytes )
|
||||
//字典相同
|
||||
if ( mDict.getMarker() == false )
|
||||
{
|
||||
//qDebug() << "相同,不写";
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
//qDebug() << "不相同,写";
|
||||
}
|
||||
//用户设置了marker标记true,强制写
|
||||
mDict.setMarker ( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
//qDebug() << "字典不同,写。";
|
||||
//字典不同
|
||||
staticDict = mDict;
|
||||
}
|
||||
|
||||
#if 0
|
||||
//如果在字典的值不同于文件里的值得时候存储,可以减少写文件次数。
|
||||
//独占式,每次读文件,减少了写次数。
|
||||
{
|
||||
QByteArray bytes1;
|
||||
readFile ( bytes1 );
|
||||
|
||||
if ( bytes1 == bytes )
|
||||
{
|
||||
qDebug() << "相同,不写";
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "不相同,写";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
QByteArray bytes;
|
||||
packDictionaryToContent ( bytes );
|
||||
writeFile ( bytes );
|
||||
}
|
||||
|
||||
|
@ -26,10 +26,9 @@
|
||||
*
|
||||
* 注意事项:
|
||||
* 如果数据文件不存在,将会自动创建文件,
|
||||
* 这个类对持久化存储数据文件的访问是“句柄”独占式,
|
||||
* 一个数据持久化类句柄对应一个数据文件,
|
||||
* 1. 用户私自写同一个数据文件,会被覆盖;
|
||||
* 2. 两个数据持久化类句柄共同写同一个数据文件,会竞争,会自动竞争写,最后一次写文件者决定文件内容。
|
||||
* 这个类对持久化存储数据文件的访问是非独占式,
|
||||
* 1. 用户私自写同一个数据文件,本句柄不会自动覆盖;
|
||||
* 2. 两个数据持久化类句柄共同写同一个数据文件,不会竞争,修改时写、Mark时写,最后一次写文件者决定文件内容。
|
||||
*
|
||||
* 使用方法:
|
||||
* QQtDataPersistence keep_inst;
|
||||
@ -37,8 +36,10 @@
|
||||
*
|
||||
* keep_inst.start(); //开始持久化数据操作 每次操作都需要开启和关闭
|
||||
* QQtDictionary& handler = keep_inst.dictionary(); //可以操作的数据句柄
|
||||
* handler["key1"]["key2"] = "value1";
|
||||
* handler.clear(); //可选:字典数据从新开始。
|
||||
* handler["key1"]["key2"] = "value1"; //字典发生改变,内部自动保存
|
||||
* ...
|
||||
* handler.marker(); // 强制保存!
|
||||
* keep_inst.stop(); //停止持久化数据操作
|
||||
*
|
||||
* keep_inst.ExitDataPersistence(); //退出持久化功能。普通buffer,不再保存数据。
|
||||
@ -65,11 +66,11 @@ public:
|
||||
void setDataFormat ( DataFormat format = JsonData );
|
||||
DataFormat dataFormat() const;
|
||||
|
||||
//持久化保存文件 [+初始化字典]
|
||||
//持久化数据文件 [+初始化字典]
|
||||
void setDataFile ( const QString& fileName );
|
||||
QString dataFile() const;
|
||||
|
||||
//打开数据持久化 [+初始化字典]
|
||||
//打开数据持久化
|
||||
void prepareDataPersistence();
|
||||
//关闭数据持久化
|
||||
void exitDataPersistence();
|
||||
|
@ -11,15 +11,32 @@
|
||||
#include "qdom.h"
|
||||
|
||||
//support yaml
|
||||
#include "yaml_cpp.h"
|
||||
#include "yaml-cpp/parser.h"
|
||||
#include "yaml-cpp/node/node.h"
|
||||
#include "yaml-cpp/yaml.h"
|
||||
|
||||
//support ini
|
||||
#include "qqtiniparser.h"
|
||||
#include "inifile.h"
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
QByteArray toIni ( const QQtDictionary& dict );
|
||||
void fromIni ( const QByteArray& bytes, QQtDictionary& dict );
|
||||
|
||||
QByteArray toProperties ( const QQtDictionary& dict );
|
||||
void fromProperties ( const QByteArray& bytes, QQtDictionary& dict );
|
||||
|
||||
QByteArray toYAML ( const QQtDictionary& dict );
|
||||
void fromYAML ( const QByteArray& yaml, QQtDictionary& dict );
|
||||
void parseYamlNodeToDictionary ( const YAML::Node& node, QQtDictionary& object );
|
||||
void packDictionaryToYamlNode ( const QQtDictionary& node, YAML::Node& object );
|
||||
|
||||
#define p3line() QNoDebug()
|
||||
|
||||
QQtDictionary::QQtDictionary ()
|
||||
{
|
||||
bMarker = false;
|
||||
m_type = DictMax;
|
||||
}
|
||||
|
||||
@ -61,6 +78,26 @@ void QQtDictionary::setType ( QQtDictionary::EDictType type )
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
void QQtDictionary::marker ()
|
||||
{
|
||||
bMarker = true;
|
||||
}
|
||||
|
||||
void QQtDictionary::reset_marker()
|
||||
{
|
||||
bMarker = false;
|
||||
}
|
||||
|
||||
bool QQtDictionary::setMarker ( bool mark )
|
||||
{
|
||||
bMarker = mark;
|
||||
}
|
||||
|
||||
bool QQtDictionary::getMarker() const
|
||||
{
|
||||
return bMarker;
|
||||
}
|
||||
|
||||
void QQtDictionary::setValue ( const QVariant& value )
|
||||
{
|
||||
m_type = DictValue;
|
||||
@ -1046,3 +1083,552 @@ QDebug operator<< ( QDebug dbg, const QQtDictionary& d )
|
||||
return dbg;
|
||||
}
|
||||
|
||||
|
||||
QByteArray toIni ( const QQtDictionary& dict )
|
||||
{
|
||||
const QQtDictionary& node = dict;
|
||||
|
||||
inifile::IniFile p0;
|
||||
switch ( dict.getType() )
|
||||
{
|
||||
case QQtDictionary::DictValue:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case QQtDictionary::DictList:
|
||||
{
|
||||
//"name":[a, b, ...]
|
||||
for ( int i = 0; i < node.getList().size(); i++ )
|
||||
{
|
||||
#if 0
|
||||
QList<QQtDictionary>& l = node.getList();
|
||||
if ( l[i].getType() == QQtDictionary::DictValue )
|
||||
{
|
||||
QString qkey = QString::number ( i );
|
||||
string key = qkey.toStdString();
|
||||
string value = l[i].getValue().toString().toStdString();
|
||||
string comment = node["__comments__"][""][qkey]["#comment"].getValue().toString().toStdString();
|
||||
string right_comment = node["__comments__"][""][qkey]["#right_comment"].getValue().toString().toStdString();
|
||||
p0.SetStringValue ( "", key, value );
|
||||
p0.SetComment ( "", key, comment );
|
||||
p0.SetRightComment ( "", key, right_comment );
|
||||
}
|
||||
#else
|
||||
const QString& sec = QString::number ( i );
|
||||
string stdsec = sec.toStdString();
|
||||
|
||||
QList<QQtDictionary>& l = node.getList();
|
||||
const QQtDictionary& srcvalue = l[i];
|
||||
|
||||
p0.AddSection ( stdsec );
|
||||
|
||||
string comment = node["__comments__"][sec]["#comment"].getValue().toString().toStdString();
|
||||
string right_comment = node["__comments__"][sec]["#right_comment"].getValue().toString().toStdString();
|
||||
p0.SetComment ( stdsec, "", comment );
|
||||
p0.SetRightComment ( stdsec, "", right_comment );
|
||||
|
||||
if ( srcvalue.getType() == QQtDictionary::DictList )
|
||||
{
|
||||
for ( int i = 0; i < srcvalue.getList().size(); i++ )
|
||||
{
|
||||
QList<QQtDictionary>& l = srcvalue.getList();
|
||||
if ( l[i].getType() == QQtDictionary::DictValue )
|
||||
{
|
||||
QString qkey = QString::number ( i );
|
||||
string key = qkey.toStdString();
|
||||
string value = l[i].getValue().toString().toStdString();
|
||||
string comment = node["__comments__"][sec][qkey]["#comment"].getValue().toString().toStdString();
|
||||
string right_comment = node["__comments__"][sec][qkey]["#right_comment"].getValue().toString().toStdString();
|
||||
p0.SetStringValue ( stdsec, key, value );
|
||||
p0.SetComment ( stdsec, key, comment );
|
||||
p0.SetRightComment ( stdsec, key, right_comment );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( srcvalue.getType() == QQtDictionary::DictMap )
|
||||
{
|
||||
for ( QMap<QString, QQtDictionary>::Iterator itor2 = srcvalue.getMap().begin();
|
||||
itor2 != srcvalue.getMap().end(); itor2++ )
|
||||
{
|
||||
//QMap<QString, QQtDictionary>& m = node.getMap();
|
||||
const QString& qkey2 = itor2.key();
|
||||
string stdkey2 = qkey2.toStdString();
|
||||
const QQtDictionary& srcvalue2 = itor2.value();
|
||||
if ( srcvalue2.getType() == QQtDictionary::DictValue )
|
||||
{
|
||||
string value = srcvalue2.getValue().toString().toStdString();
|
||||
string comment = node["__comments__"][sec][qkey2]["#comment"].getValue().toString().toStdString();
|
||||
string right_comment = node["__comments__"][sec][qkey2]["#right_comment"].getValue().toString().toStdString();
|
||||
p0.SetStringValue ( stdsec, stdkey2, value );
|
||||
p0.SetComment ( stdsec, stdkey2, comment );
|
||||
p0.SetRightComment ( stdsec, stdkey2, right_comment );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QQtDictionary::DictMap:
|
||||
{
|
||||
//"name": {"a":"b", "a2":"b2", "a3":["b31", "b32"], "a4":{"a41":"b41", "a42":"b42"}, ...}
|
||||
for ( QMap<QString, QQtDictionary>::Iterator itor = node.getMap().begin();
|
||||
itor != node.getMap().end(); itor++ )
|
||||
{
|
||||
//QMap<QString, QQtDictionary>& m = node.getMap();
|
||||
const QString& sec = itor.key();
|
||||
string stdsec = sec.toStdString();
|
||||
const QQtDictionary& srcvalue = itor.value();
|
||||
|
||||
if ( sec == "__comments__" )
|
||||
continue;
|
||||
|
||||
p0.AddSection ( stdsec );
|
||||
|
||||
string comment = node["__comments__"][sec]["#comment"].getValue().toString().toStdString();
|
||||
string right_comment = node["__comments__"][sec]["#right_comment"].getValue().toString().toStdString();
|
||||
//qDebug() << QString::fromStdString ( comment );
|
||||
//qDebug() << QString::fromStdString ( right_comment );
|
||||
int ret;
|
||||
ret = p0.SetComment ( stdsec, "", comment );
|
||||
//qDebug() << ret;
|
||||
ret = p0.SetRightComment ( stdsec, "", right_comment );
|
||||
//qDebug() << ret;
|
||||
|
||||
if ( srcvalue.getType() == QQtDictionary::DictList )
|
||||
{
|
||||
for ( int i = 0; i < srcvalue.getList().size(); i++ )
|
||||
{
|
||||
QList<QQtDictionary>& l = srcvalue.getList();
|
||||
if ( l[i].getType() == QQtDictionary::DictValue )
|
||||
{
|
||||
QString qkey = QString::number ( i );
|
||||
string key = qkey.toStdString();
|
||||
string value = l[i].getValue().toString().toStdString();
|
||||
string comment = node["__comments__"][sec][qkey]["#comment"].getValue().toString().toStdString();
|
||||
string right_comment = node["__comments__"][sec][qkey]["#right_comment"].getValue().toString().toStdString();
|
||||
p0.SetStringValue ( stdsec, key, value );
|
||||
p0.SetComment ( stdsec, key, comment );
|
||||
p0.SetRightComment ( stdsec, key, right_comment );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( srcvalue.getType() == QQtDictionary::DictMap )
|
||||
{
|
||||
for ( QMap<QString, QQtDictionary>::Iterator itor2 = srcvalue.getMap().begin();
|
||||
itor2 != srcvalue.getMap().end(); itor2++ )
|
||||
{
|
||||
//QMap<QString, QQtDictionary>& m = node.getMap();
|
||||
const QString& qkey2 = itor2.key();
|
||||
string stdkey2 = qkey2.toStdString();
|
||||
const QQtDictionary& srcvalue2 = itor2.value();
|
||||
if ( srcvalue2.getType() == QQtDictionary::DictValue )
|
||||
{
|
||||
string value = srcvalue2.getValue().toString().toStdString();
|
||||
string comment = node["__comments__"][sec][qkey2]["#comment"].getValue().toString().toStdString();
|
||||
string right_comment = node["__comments__"][sec][qkey2]["#right_comment"].getValue().toString().toStdString();
|
||||
p0.SetStringValue ( stdsec, stdkey2, value );
|
||||
p0.SetComment ( stdsec, stdkey2, comment );
|
||||
p0.SetRightComment ( stdsec, stdkey2, right_comment );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QQtDictionary::DictMax:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
int ret;
|
||||
|
||||
std::string buffer;
|
||||
ret = p0.SaveToContent ( buffer );
|
||||
//qDebug() << ret;
|
||||
|
||||
QByteArray bytes = QByteArray::fromStdString ( buffer );
|
||||
//qDebug() << qPrintable ( bytes );
|
||||
|
||||
//不返回会崩溃
|
||||
return bytes;
|
||||
}
|
||||
|
||||
void fromIni ( const QByteArray& bytes, QQtDictionary& dict )
|
||||
{
|
||||
inifile::IniFile p0;
|
||||
int ret;
|
||||
ret = p0.LoadFromContent ( bytes.toStdString() );
|
||||
|
||||
//qDebug() << ret;
|
||||
vector<string> secs;
|
||||
ret = p0.GetSections ( &secs );
|
||||
for ( vector<string>::iterator itor = secs.begin();
|
||||
itor != secs.end(); itor++ )
|
||||
{
|
||||
string& secName = *itor;
|
||||
inifile::IniSection* sec = p0.getSection ( secName );
|
||||
//sec name
|
||||
string name = sec->name; QString qname = QString::fromStdString ( name );
|
||||
//sec comment
|
||||
string comment = sec->comment; QString qcomment = QString::fromStdString ( comment );
|
||||
//sec right_comment
|
||||
string right_comment = sec->rightComment; QString qright_comment = QString::fromStdString ( right_comment );
|
||||
|
||||
dict["__comments__"][qname]["#comment"] = qcomment;
|
||||
dict["__comments__"][qname]["#right_comment"] = qright_comment;
|
||||
|
||||
//sec child
|
||||
for ( inifile::IniSection::IniItem_it it = sec->begin();
|
||||
it != sec->end(); it++ )
|
||||
{
|
||||
inifile::IniItem& item = *it;
|
||||
|
||||
//#comment
|
||||
string comment = item.comment; QString qcomment = QString::fromStdString ( comment );
|
||||
//#right_comment
|
||||
string right_comment = item.rightComment; QString qright_comment = QString::fromStdString ( right_comment );
|
||||
//key
|
||||
string key = item.key; QString qkey = QString::fromStdString ( key );
|
||||
//value
|
||||
string value = item.value; QString qvalue = QString::fromStdString ( value );
|
||||
|
||||
dict["__comments__"][qname][qkey]["#comment"] = qcomment;
|
||||
dict["__comments__"][qname][qkey]["#right_comment"] = qright_comment;
|
||||
dict[qname][qkey] = qvalue;
|
||||
}
|
||||
}
|
||||
|
||||
//qDebug() << qPrintable ( dict.toJson ( QJsonDocument::Indented ) );
|
||||
}
|
||||
|
||||
QByteArray toProperties ( const QQtDictionary& dict )
|
||||
{
|
||||
const QQtDictionary& node = dict;
|
||||
|
||||
inifile::IniFile p0;
|
||||
switch ( dict.getType() )
|
||||
{
|
||||
case QQtDictionary::DictValue:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case QQtDictionary::DictList:
|
||||
{
|
||||
//"name":[a, b, ...]
|
||||
for ( int i = 0; i < node.getList().size(); i++ )
|
||||
{
|
||||
#if 0
|
||||
QList<QQtDictionary>& l = node.getList();
|
||||
if ( l[i].getType() == QQtDictionary::DictValue )
|
||||
{
|
||||
QString qkey = QString::number ( i );
|
||||
string key = qkey.toStdString();
|
||||
string value = l[i].getValue().toString().toStdString();
|
||||
string comment = node["__comments__"][""][qkey]["#comment"].getValue().toString().toStdString();
|
||||
string right_comment = node["__comments__"][""][qkey]["#right_comment"].getValue().toString().toStdString();
|
||||
p0.SetStringValue ( "", key, value );
|
||||
p0.SetComment ( "", key, comment );
|
||||
p0.SetRightComment ( "", key, right_comment );
|
||||
}
|
||||
#elif 0
|
||||
const QString& sec = QString::number ( i );
|
||||
string stdsec = sec.toStdString();
|
||||
|
||||
QList<QQtDictionary>& l = node.getList();
|
||||
const QQtDictionary& srcvalue = l[i];
|
||||
|
||||
p0.AddSection ( stdsec );
|
||||
|
||||
string comment = node["__comments__"][sec]["#comment"].getValue().toString().toStdString();
|
||||
string right_comment = node["__comments__"][sec]["#right_comment"].getValue().toString().toStdString();
|
||||
p0.SetComment ( stdsec, "", comment );
|
||||
p0.SetRightComment ( stdsec, "", right_comment );
|
||||
|
||||
if ( srcvalue.getType() == QQtDictionary::DictList )
|
||||
{
|
||||
for ( int i = 0; i < srcvalue.getList().size(); i++ )
|
||||
{
|
||||
QList<QQtDictionary>& l = srcvalue.getList();
|
||||
if ( l[i].getType() == QQtDictionary::DictValue )
|
||||
{
|
||||
QString qkey = QString::number ( i );
|
||||
string key = qkey.toStdString();
|
||||
string value = l[i].getValue().toString().toStdString();
|
||||
string comment = node["__comments__"][sec][qkey]["#comment"].getValue().toString().toStdString();
|
||||
string right_comment = node["__comments__"][sec][qkey]["#right_comment"].getValue().toString().toStdString();
|
||||
p0.SetStringValue ( stdsec, key, value );
|
||||
p0.SetComment ( stdsec, key, comment );
|
||||
p0.SetRightComment ( stdsec, key, right_comment );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( srcvalue.getType() == QQtDictionary::DictMap )
|
||||
{
|
||||
for ( QMap<QString, QQtDictionary>::Iterator itor2 = srcvalue.getMap().begin();
|
||||
itor2 != srcvalue.getMap().end(); itor2++ )
|
||||
{
|
||||
//QMap<QString, QQtDictionary>& m = node.getMap();
|
||||
const QString& qkey2 = itor2.key();
|
||||
string stdkey2 = qkey2.toStdString();
|
||||
const QQtDictionary& srcvalue2 = itor2.value();
|
||||
if ( srcvalue2.getType() == QQtDictionary::DictValue )
|
||||
{
|
||||
string value = srcvalue2.getValue().toString().toStdString();
|
||||
string comment = node["__comments__"][sec][qkey2]["#comment"].getValue().toString().toStdString();
|
||||
string right_comment = node["__comments__"][sec][qkey2]["#right_comment"].getValue().toString().toStdString();
|
||||
p0.SetStringValue ( stdsec, stdkey2, value );
|
||||
p0.SetComment ( stdsec, stdkey2, comment );
|
||||
p0.SetRightComment ( stdsec, stdkey2, right_comment );
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
const QString& key = QString::number ( i );
|
||||
string stdkey = key.toStdString();
|
||||
QList<QQtDictionary>& l = node.getList();
|
||||
const QQtDictionary& srcvalue = l[i];
|
||||
|
||||
if ( key == "__comments__" )
|
||||
continue;
|
||||
|
||||
if ( srcvalue.getType() != QQtDictionary::DictValue )
|
||||
continue;
|
||||
|
||||
p0.AddSection ( "" );
|
||||
|
||||
string value = srcvalue.getValue().toString().toStdString();
|
||||
string comment = node["__comments__"][key]["#comment"].getValue().toString().toStdString();
|
||||
string right_comment = node["__comments__"][key]["#right_comment"].getValue().toString().toStdString();
|
||||
p0.SetStringValue ( "", stdkey, value );
|
||||
p0.SetComment ( "", stdkey, comment );
|
||||
p0.SetRightComment ( "", stdkey, right_comment );
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QQtDictionary::DictMap:
|
||||
{
|
||||
//"name": {"a":"b", "a2":"b2", "a3":["b31", "b32"], "a4":{"a41":"b41", "a42":"b42"}, ...}
|
||||
for ( QMap<QString, QQtDictionary>::Iterator itor = node.getMap().begin();
|
||||
itor != node.getMap().end(); itor++ )
|
||||
{
|
||||
//QMap<QString, QQtDictionary>& m = node.getMap();
|
||||
const QString& key = itor.key();
|
||||
string stdkey = key.toStdString();
|
||||
const QQtDictionary& srcvalue = itor.value();
|
||||
|
||||
if ( key == "__comments__" )
|
||||
continue;
|
||||
|
||||
if ( srcvalue.getType() != QQtDictionary::DictValue )
|
||||
continue;
|
||||
|
||||
p0.AddSection ( "" );
|
||||
|
||||
string value = srcvalue.getValue().toString().toStdString();
|
||||
string comment = node["__comments__"][key]["#comment"].getValue().toString().toStdString();
|
||||
string right_comment = node["__comments__"][key]["#right_comment"].getValue().toString().toStdString();
|
||||
p0.SetStringValue ( "", stdkey, value );
|
||||
p0.SetComment ( "", stdkey, comment );
|
||||
p0.SetRightComment ( "", stdkey, right_comment );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QQtDictionary::DictMax:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
int ret;
|
||||
|
||||
std::string buffer;
|
||||
ret = p0.SaveToContent ( buffer );
|
||||
//qDebug() << ret;
|
||||
|
||||
QByteArray bytes = QByteArray::fromStdString ( buffer );
|
||||
//qDebug() << qPrintable ( bytes );
|
||||
|
||||
//不返回会崩溃
|
||||
return bytes;
|
||||
}
|
||||
|
||||
void fromProperties ( const QByteArray& bytes, QQtDictionary& dict )
|
||||
{
|
||||
inifile::IniFile p0;
|
||||
int ret;
|
||||
ret = p0.LoadFromContent ( bytes.toStdString() );
|
||||
|
||||
//qDebug() << ret;
|
||||
vector<string> secs;
|
||||
ret = p0.GetSections ( &secs );
|
||||
for ( vector<string>::iterator itor = secs.begin();
|
||||
itor != secs.end(); itor++ )
|
||||
{
|
||||
string& secName = *itor;
|
||||
if ( secName != "" )
|
||||
continue;
|
||||
|
||||
inifile::IniSection* sec = p0.getSection ( secName );
|
||||
//sec child
|
||||
for ( inifile::IniSection::IniItem_it it = sec->begin();
|
||||
it != sec->end(); it++ )
|
||||
{
|
||||
inifile::IniItem& item = *it;
|
||||
|
||||
//#comment
|
||||
string comment = item.comment; QString qcomment = QString::fromStdString ( comment );
|
||||
//#right_comment
|
||||
string right_comment = item.rightComment; QString qright_comment = QString::fromStdString ( right_comment );
|
||||
//key
|
||||
string key = item.key; QString qkey = QString::fromStdString ( key );
|
||||
//value
|
||||
string value = item.value; QString qvalue = QString::fromStdString ( value );
|
||||
|
||||
dict["__comments__"][qkey]["#comment"] = qcomment;
|
||||
dict["__comments__"][qkey]["#right_comment"] = qright_comment;
|
||||
dict[qkey] = qvalue;
|
||||
}
|
||||
}
|
||||
|
||||
//qDebug() << qPrintable ( dict.toJson ( QJsonDocument::Indented ) );
|
||||
}
|
||||
|
||||
|
||||
QByteArray toYAML ( const QQtDictionary& dict )
|
||||
{
|
||||
|
||||
YAML::Node node;
|
||||
packDictionaryToYamlNode ( dict, node );
|
||||
//std::cout << "================(A)=============" << std::endl;
|
||||
//std::cout << node << std::endl;
|
||||
|
||||
|
||||
std::string buffer;
|
||||
buffer = YAML::Dump ( node );
|
||||
|
||||
QByteArray bytes;
|
||||
bytes = QByteArray::fromStdString ( buffer );
|
||||
|
||||
//std::cout << "================(B)=============" << std::endl;
|
||||
//qDebug() << qPrintable ( bytes );
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
void fromYAML ( const QByteArray& yaml, QQtDictionary& dict )
|
||||
{
|
||||
|
||||
//这个东西非常容易崩溃。
|
||||
YAML::Node config;
|
||||
|
||||
#if 1
|
||||
try
|
||||
{
|
||||
config = YAML::Load ( yaml );
|
||||
//std::cout << config << std::endl;
|
||||
}
|
||||
catch ( const YAML::Exception& e )
|
||||
{
|
||||
//-—
|
||||
//? [ bad conversion but exited crashed
|
||||
std::cerr << e.what() << std::endl;
|
||||
return;
|
||||
}
|
||||
#elif 0
|
||||
//YAML::Parser parser();
|
||||
#else
|
||||
config = YAML::Load ( yaml );
|
||||
#endif
|
||||
|
||||
|
||||
parseYamlNodeToDictionary ( config, dict );
|
||||
//qDebug() << "=================";
|
||||
//qDebug() << dict;
|
||||
//qDebug() << qPrintable ( QString ( dict.toJson ( QJsonDocument::Indented ) ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void parseYamlNodeToDictionary ( const YAML::Node& node, QQtDictionary& object )
|
||||
{
|
||||
if ( node.IsNull() )
|
||||
{
|
||||
//qDebug() << "empty value"; //null
|
||||
object = QString();
|
||||
}
|
||||
else if ( node.IsScalar() )
|
||||
{
|
||||
//auto it = node.begin();
|
||||
//qDebug() << QString::fromStdString ( node.Scalar() );
|
||||
object = QString::fromStdString ( node.Scalar() );
|
||||
}
|
||||
else if ( node.IsSequence() )
|
||||
{
|
||||
int id = 0;
|
||||
for ( YAML::Node::const_iterator it = node.begin(); it != node.end(); ++it )
|
||||
{
|
||||
const YAML::Node& obj = *it;
|
||||
parseYamlNodeToDictionary ( obj, object[id++] );
|
||||
}
|
||||
}
|
||||
else if ( node.IsMap() )
|
||||
{
|
||||
for ( YAML::Node::const_iterator it = node.begin(); it != node.end(); ++it )
|
||||
{
|
||||
//qDebug() << QString::fromStdString ( it->first.as<string>() ) << ":" << it->second.Type();
|
||||
QString key = QString::fromStdString ( it->first.as<string>() ) ;
|
||||
parseYamlNodeToDictionary ( it->second, object[key] );
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void packDictionaryToYamlNode ( const QQtDictionary& node, YAML::Node& object )
|
||||
{
|
||||
switch ( node.getType() )
|
||||
{
|
||||
case QQtDictionary:: DictValue:
|
||||
{
|
||||
//null, bool, double, string
|
||||
std::string value = node.getValue().toString().toStdString();
|
||||
object = value;
|
||||
break;
|
||||
}
|
||||
case QQtDictionary:: DictList:
|
||||
{
|
||||
//"name":[a, b, ...]
|
||||
for ( int i = 0; i < node.getList().size(); i++ )
|
||||
{
|
||||
QList<QQtDictionary>& l = node.getList();
|
||||
YAML::Node value;
|
||||
packDictionaryToYamlNode ( l[i], value );
|
||||
object.push_back ( value );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QQtDictionary:: DictMap:
|
||||
{
|
||||
//"name": {"a":"b", "a2":"b2", "a3":["b31", "b32"], "a4":{"a41":"b41", "a42":"b42"}, ...}
|
||||
for ( QMap<QString, QQtDictionary>::Iterator itor = node.getMap().begin(); itor != node.getMap().end(); itor++ )
|
||||
{
|
||||
//QMap<QString, QQtDictionary>& m = node.getMap();
|
||||
const QString& qkey = itor.key();
|
||||
std::string key = qkey.toStdString();
|
||||
const QQtDictionary& srcvalue = itor.value();
|
||||
YAML::Node value;
|
||||
packDictionaryToYamlNode ( srcvalue, value );
|
||||
object[key] = value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QQtDictionary:: DictMax:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -106,6 +106,15 @@ public:
|
||||
/*如果设置Value的时候改变了Type,将会以新的Type为准*/
|
||||
void setType ( EDictType type );
|
||||
|
||||
/*设置标记*/
|
||||
void marker ();
|
||||
/*重置标记*/
|
||||
void reset_marker ();
|
||||
/*设置标记 default: true*/
|
||||
bool setMarker ( bool mark = true );
|
||||
/*获取标记 default: false*/
|
||||
bool getMarker() const;
|
||||
|
||||
//设置value
|
||||
template <typename T>
|
||||
void setValue ( const T& value ) {
|
||||
@ -207,6 +216,9 @@ signals:
|
||||
public slots:
|
||||
|
||||
private:
|
||||
/*一个标记*/
|
||||
bool bMarker;
|
||||
|
||||
/*节点类型,指示性变量*/
|
||||
EDictType m_type;
|
||||
|
||||
|
@ -1,144 +1,2 @@
|
||||
#include "yaml_cpp.h"
|
||||
|
||||
|
||||
#include "yaml-cpp/parser.h"
|
||||
#include "yaml-cpp/node/node.h"
|
||||
#include "yaml-cpp/yaml.h"
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
|
||||
QByteArray toYAML ( const QQtDictionary& dict )
|
||||
{
|
||||
|
||||
YAML::Node node;
|
||||
packDictionaryToYamlNode ( dict, node );
|
||||
//std::cout << "================(A)=============" << std::endl;
|
||||
//std::cout << node << std::endl;
|
||||
|
||||
|
||||
std::string buffer;
|
||||
buffer = YAML::Dump ( node );
|
||||
|
||||
QByteArray bytes;
|
||||
bytes = QByteArray::fromStdString ( buffer );
|
||||
|
||||
//std::cout << "================(B)=============" << std::endl;
|
||||
//qDebug() << qPrintable ( bytes );
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
void fromYAML ( const QByteArray& yaml, QQtDictionary& dict )
|
||||
{
|
||||
|
||||
//这个东西非常容易崩溃。
|
||||
YAML::Node config;
|
||||
|
||||
#if 1
|
||||
try
|
||||
{
|
||||
config = YAML::Load ( yaml );
|
||||
//std::cout << config << std::endl;
|
||||
}
|
||||
catch ( const YAML::Exception& e )
|
||||
{
|
||||
//-—
|
||||
//? [ bad conversion but exited crashed
|
||||
std::cerr << e.what() << std::endl;
|
||||
return;
|
||||
}
|
||||
#elif 0
|
||||
//YAML::Parser parser();
|
||||
#else
|
||||
config = YAML::Load ( yaml );
|
||||
#endif
|
||||
|
||||
|
||||
parseYamlNodeToDictionary ( config, dict );
|
||||
//qDebug() << "=================";
|
||||
//qDebug() << dict;
|
||||
//qDebug() << qPrintable ( QString ( dict.toJson ( QJsonDocument::Indented ) ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void parseYamlNodeToDictionary ( const YAML::Node& node, QQtDictionary& object )
|
||||
{
|
||||
if ( node.IsNull() )
|
||||
{
|
||||
//qDebug() << "empty value"; //null
|
||||
object = QString();
|
||||
}
|
||||
else if ( node.IsScalar() )
|
||||
{
|
||||
//auto it = node.begin();
|
||||
//qDebug() << QString::fromStdString ( node.Scalar() );
|
||||
object = QString::fromStdString ( node.Scalar() );
|
||||
}
|
||||
else if ( node.IsSequence() )
|
||||
{
|
||||
int id = 0;
|
||||
for ( YAML::Node::const_iterator it = node.begin(); it != node.end(); ++it )
|
||||
{
|
||||
const YAML::Node& obj = *it;
|
||||
parseYamlNodeToDictionary ( obj, object[id++] );
|
||||
}
|
||||
}
|
||||
else if ( node.IsMap() )
|
||||
{
|
||||
for ( YAML::Node::const_iterator it = node.begin(); it != node.end(); ++it )
|
||||
{
|
||||
//qDebug() << QString::fromStdString ( it->first.as<string>() ) << ":" << it->second.Type();
|
||||
QString key = QString::fromStdString ( it->first.as<string>() ) ;
|
||||
parseYamlNodeToDictionary ( it->second, object[key] );
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void packDictionaryToYamlNode ( const QQtDictionary& node, YAML::Node& object )
|
||||
{
|
||||
switch ( node.getType() )
|
||||
{
|
||||
case QQtDictionary:: DictValue:
|
||||
{
|
||||
//null, bool, double, string
|
||||
std::string value = node.getValue().toString().toStdString();
|
||||
object = value;
|
||||
break;
|
||||
}
|
||||
case QQtDictionary:: DictList:
|
||||
{
|
||||
//"name":[a, b, ...]
|
||||
for ( int i = 0; i < node.getList().size(); i++ )
|
||||
{
|
||||
QList<QQtDictionary>& l = node.getList();
|
||||
YAML::Node value;
|
||||
packDictionaryToYamlNode ( l[i], value );
|
||||
object.push_back ( value );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QQtDictionary:: DictMap:
|
||||
{
|
||||
//"name": {"a":"b", "a2":"b2", "a3":["b31", "b32"], "a4":{"a41":"b41", "a42":"b42"}, ...}
|
||||
for ( QMap<QString, QQtDictionary>::Iterator itor = node.getMap().begin(); itor != node.getMap().end(); itor++ )
|
||||
{
|
||||
//QMap<QString, QQtDictionary>& m = node.getMap();
|
||||
const QString& qkey = itor.key();
|
||||
std::string key = qkey.toStdString();
|
||||
const QQtDictionary& srcvalue = itor.value();
|
||||
YAML::Node value;
|
||||
packDictionaryToYamlNode ( srcvalue, value );
|
||||
object[key] = value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QQtDictionary:: DictMax:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,17 +1,13 @@
|
||||
#ifndef YAML_CPP_H
|
||||
#define YAML_CPP_H
|
||||
|
||||
#include <qqtdictionary.h>
|
||||
|
||||
#include "yaml-cpp/emitterstyle.h"
|
||||
#include "yaml-cpp/eventhandler.h"
|
||||
#include "yaml-cpp/parser.h"
|
||||
#include "yaml-cpp/node/node.h"
|
||||
#include "yaml-cpp/yaml.h"
|
||||
|
||||
#include "yaml_cpp_global.h"
|
||||
|
||||
class YAML_CPPSHARED_EXPORT NullEventHandler : public YAML::EventHandler
|
||||
class NullEventHandler : public YAML::EventHandler
|
||||
{
|
||||
public:
|
||||
typedef YAML::Mark Mark;
|
||||
@ -33,10 +29,5 @@ public:
|
||||
virtual void OnMapEnd() {}
|
||||
};
|
||||
|
||||
YAML_CPPSHARED_EXPORT QByteArray toYAML ( const QQtDictionary& dict );
|
||||
YAML_CPPSHARED_EXPORT void fromYAML ( const QByteArray& yaml, QQtDictionary& dict );
|
||||
|
||||
YAML_CPPSHARED_EXPORT void parseYamlNodeToDictionary ( const YAML::Node& node, QQtDictionary& object );
|
||||
YAML_CPPSHARED_EXPORT void packDictionaryToYamlNode ( const QQtDictionary& node, YAML::Node& object );
|
||||
|
||||
#endif // YAML_CPP_H
|
||||
|
@ -65,7 +65,8 @@ void MainWindow::on_pushButton_clicked ( bool checked )
|
||||
//不清空就是和原字典合并,
|
||||
handler.clear();
|
||||
handler.fromJson ( bytes );
|
||||
//旁边的按钮更改了内部数据,又给改回去了,只好force write。
|
||||
//旁边的按钮更改了内部数据,又给改回去了,只好force write,marker()。
|
||||
handler.marker();
|
||||
|
||||
dp0.stop();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user