572 lines
9.4 KiB
C++
572 lines
9.4 KiB
C++
//-----------------------------------------------------------------------------+
|
|
// Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd.
|
|
// = FileName : TWDict 类
|
|
// = Version : ver2.0
|
|
// = Author : wlw
|
|
// = CreateDate : 2002-09-09
|
|
// = Description: TWDict 定义
|
|
// = Maintainers:
|
|
//
|
|
//-----------------------------------------------------------------------------+
|
|
#include "StdAfx.h"
|
|
#include "TWDict.h"
|
|
#include "TWBoolItem.h"
|
|
#include "TWCharItem.h"
|
|
#include "TWLongItem.h"
|
|
#include "TWDoubleItem.h"
|
|
#include "TWCStringItem.h"
|
|
#include "TWSelectItem.h"
|
|
|
|
|
|
TWDict::TWDict(const TCHAR* sName, const TCHAR *sDesc)
|
|
: TWDictItem(sName,sDesc)
|
|
{
|
|
|
|
}
|
|
|
|
TWDict::~TWDict()
|
|
{
|
|
|
|
}
|
|
|
|
int TWDict::GetType()const
|
|
{
|
|
return TYPE_WDict;
|
|
}
|
|
|
|
TWDictItem* TWDict::FindItem(const CString &sPath)
|
|
{
|
|
TWDictPath ss(sPath);
|
|
return FindItem(ss);
|
|
}
|
|
|
|
//无论是否添加成功,GetCurPData()==*pNewItem!
|
|
bool TWDict::AppendItem(TWDictItem*pNewItem)
|
|
{
|
|
if (!pNewItem->IsValid())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return SortIn(pNewItem);//二分法查找添加
|
|
}
|
|
|
|
bool TWDict::AppendItem(const CString &sPath, TWDictItem *pNewItem)
|
|
{
|
|
TWDictItem *pItem = FindItem(sPath);
|
|
if (pItem == NULL || !pItem->IsDict())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
TWDict*pDict = (TWDict*)pItem;
|
|
return pDict->AppendItem(pNewItem);
|
|
}
|
|
|
|
TWDictItem* TWDict::FindItem(TWDictPath &path)
|
|
{
|
|
if (path.IsEmpty())
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
if (BFindDataTo(path(0))) //二分法查找
|
|
{
|
|
TWDictItem* pItem = GetCurData();
|
|
if (path.GetLength() == 1)
|
|
{
|
|
return pItem;
|
|
}
|
|
else if (pItem->IsDict()) //继续在子字典中找
|
|
{
|
|
TWDict* pDict = (TWDict*)pItem;
|
|
path.DelFirst();
|
|
|
|
return pDict->FindItem(path);
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
TWDict* TWDict::FindOrAddDict(TWDictPath&path)
|
|
{
|
|
if (path.IsEmpty())
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
TWDict*pDict = new TWDict(path(0).m_sName);
|
|
if (!AppendItem(pDict)) //是否已经存在
|
|
{
|
|
delete pDict;
|
|
if (GetCurData()->IsDict())
|
|
{
|
|
pDict = (TWDict*)GetCurData();
|
|
}
|
|
else //非字典项占用
|
|
{
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
path.DelFirst();
|
|
if (path.IsEmpty()) //直接子字典
|
|
{
|
|
return pDict;
|
|
}
|
|
else //继续查找
|
|
{
|
|
return pDict->FindOrAddDict(path);
|
|
}
|
|
}
|
|
|
|
TWDict* TWDict::FindOrAddDict(const CString &sPath)
|
|
{
|
|
TWDictPath path(sPath);
|
|
if (!path.IsValid())
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
return FindOrAddDict(path);
|
|
}
|
|
|
|
TWDictItem* TWDict::FindOrAddItem(const CString &sPath, int type)
|
|
{
|
|
TWDictPath path(sPath);
|
|
if (!path.IsValid())
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
if (path.GetLength() == 1) //无中间层
|
|
{
|
|
TWDictItem *pItem = DynCreateItem(type);
|
|
if (pItem == NULL) //无法识别的数据类型!
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
pItem->m_sName = path(0).m_sName;
|
|
if (!AppendItem(pItem)) //已经存在
|
|
{
|
|
delete pItem;
|
|
}
|
|
|
|
return GetCurData();
|
|
}
|
|
else //需要中间层
|
|
{
|
|
CString sLast = path(path.GetLastIndex()).m_sName;
|
|
path.DelTail(); //成为子字典路径
|
|
|
|
TWDict *pDict = FindOrAddDict(path);
|
|
if (pDict == NULL) //中间层建立失败
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
TWDictItem *pItem = DynCreateItem(type);
|
|
if (pItem == NULL) //无法识别的数据类型!
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
pItem->m_sName = sLast;
|
|
if (!pDict->AppendItem(pItem)) //已经存在
|
|
{
|
|
delete pItem;
|
|
}
|
|
|
|
return pDict->GetCurData();
|
|
}
|
|
}
|
|
|
|
bool TWDict::SetValue(const CString &sPath, bool value)
|
|
{
|
|
TWDictItem *pItem = FindOrAddItem(sPath,1);
|
|
if (pItem == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
TWBoolItem *pItem1 = (TWBoolItem*)pItem;
|
|
pItem1->m_data = value;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool TWDict::SetValue(const CString &sPath, char value)
|
|
{
|
|
TWDictItem *pItem = FindOrAddItem(sPath,2);
|
|
if (pItem == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
TWCharItem *pItem1 = (TWCharItem*)pItem;
|
|
pItem1->m_data = value;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool TWDict::SetValue(const CString &sPath, int value)
|
|
{
|
|
TWDictItem *pItem = FindOrAddItem(sPath,3);
|
|
if (pItem == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
TWLongItem *pItem1 = (TWLongItem*)pItem;
|
|
pItem1->m_data = value;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool TWDict::SetValue(const CString &sPath, long value)
|
|
{
|
|
TWDictItem *pItem = FindOrAddItem(sPath,3);
|
|
if (pItem == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
TWLongItem *pItem1 = (TWLongItem*)pItem;
|
|
pItem1->m_data = value;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool TWDict::SetValue(const CString &sPath, double value)
|
|
{
|
|
TWDictItem *pItem = FindOrAddItem(sPath,4);
|
|
if (pItem == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
TWDoubleItem *pItem1 = (TWDoubleItem*)pItem;
|
|
pItem1->m_data = value;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool TWDict::SetValue(const CString &sPath, const CString& value)
|
|
{
|
|
TWDictItem *pItem = FindOrAddItem(sPath,5);
|
|
if (pItem == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
TWCStringItem *pItem1 = (TWCStringItem*)pItem;
|
|
pItem1->m_data = value;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool TWDict::SetValue(const CString &sPath, unsigned int value)
|
|
{
|
|
TWDictItem *pItem = FindOrAddItem(sPath,4);
|
|
if (pItem == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
TWSelectItem *pItem1 = (TWSelectItem*)pItem;
|
|
if (pItem1->IsValidIndex(value))
|
|
{
|
|
pItem1->m_data = value;
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool TWDict::GetValue(const CString &sPath, bool &value)
|
|
{
|
|
TWDictItem *pItem = FindItem(sPath);
|
|
if (pItem == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
TWBoolItem *pItem1 = (TWBoolItem*)pItem;
|
|
value = pItem1->m_data == TRUE;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool TWDict::GetValue(const CString &sPath, char &value)
|
|
{
|
|
TWDictItem *pItem = FindItem(sPath);
|
|
if (pItem == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
TWCharItem *pItem1 = (TWCharItem*)pItem;
|
|
value = pItem1->m_data;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool TWDict::GetValue(const CString &sPath, long &value)
|
|
{
|
|
TWDictItem *pItem = FindItem(sPath);
|
|
if (pItem == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
TWLongItem *pItem1 = (TWLongItem*)pItem;
|
|
value = pItem1->m_data;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool TWDict::GetValue(const CString &sPath, int &value)
|
|
{
|
|
TWDictItem *pItem = FindItem(sPath);
|
|
if (pItem == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
TWLongItem *pItem1 = (TWLongItem*)pItem;
|
|
value = pItem1->m_data;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool TWDict::GetValue(const CString &sPath, double &value)
|
|
{
|
|
TWDictItem *pItem = FindItem(sPath);
|
|
if (pItem == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
TWDoubleItem *pItem1 = (TWDoubleItem*)pItem;
|
|
value = pItem1->m_data;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool TWDict::GetValue(const CString &sPath, CString &value)
|
|
{
|
|
TWDictItem *pItem = FindItem(sPath);
|
|
if (pItem == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
TWCStringItem *pItem1 = (TWCStringItem*)pItem;
|
|
value = pItem1->m_data;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool TWDict::GetValue(const CString &sPath, unsigned int &value)
|
|
{
|
|
TWDictItem *pItem = FindItem(sPath);
|
|
if (pItem == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
TWSelectItem *pItem1 = (TWSelectItem*)pItem;
|
|
value = pItem1->m_data;
|
|
|
|
return true;
|
|
}
|
|
|
|
void TWDict::operator>>(CArchive &ar)
|
|
{
|
|
TWDictItem::operator >> (ar);
|
|
ar << GetLength();
|
|
|
|
for (MoveToFirst(); !IsOut(); MoveToNext())
|
|
{
|
|
GetCurPData() >> ar;
|
|
}
|
|
}
|
|
|
|
void TWDict::operator << (CArchive &ar)
|
|
{
|
|
TWDictItem::operator << (ar);
|
|
|
|
long len;
|
|
ar >> len;
|
|
|
|
Clear();
|
|
for (long i = 0; i < len; i++)
|
|
{
|
|
int type;
|
|
ar >> type;
|
|
|
|
TWDictItem *pItem = DynCreateItem(type);
|
|
if (pItem == NULL)
|
|
{
|
|
break; //无法识别的数据类型!
|
|
}
|
|
else
|
|
{
|
|
*pItem << ar;
|
|
AddTail(pItem);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool TWDict::ReadFile(const TCHAR *sFile)
|
|
{
|
|
/*CString strFile(sFile);
|
|
strFile.Replace(_T(".ini"), _T(".json"));
|
|
|
|
WDocument doc;
|
|
doc.SetObject();
|
|
TWDictItem::file2Json(strFile, doc);
|
|
|
|
loadByJson(doc);*/
|
|
CFile file;
|
|
if (!file.Open(sFile,CFile::modeRead))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
CArchive ar(&file, CArchive::load);
|
|
int type;
|
|
ar >> type;
|
|
(*this) << ar;
|
|
ar.Flush();
|
|
|
|
file.Close();
|
|
|
|
return true;
|
|
}
|
|
|
|
bool TWDict::WriteFile(const TCHAR *sFile)
|
|
{
|
|
CFile file;
|
|
if (!file.Open(sFile,CFile::modeCreate | CFile::modeWrite))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
file.SetLength(0);
|
|
file.Flush();
|
|
|
|
CArchive ar(&file,CArchive::store);
|
|
(*this) >> ar;
|
|
ar.Flush();
|
|
|
|
file.Close();
|
|
|
|
/*CString strFile(sFile);
|
|
strFile.Replace(_T(".ini"), _T(".json"));
|
|
|
|
WValue v;
|
|
v.SetObject();
|
|
saveToJson(v);
|
|
TWDictItem::json2File(strFile, v, true);*/
|
|
|
|
return true;
|
|
}
|
|
|
|
void TWDict::CopyData(const TWDictItem&src)
|
|
{
|
|
if (GetType() != src.GetType())
|
|
{
|
|
return;
|
|
}
|
|
|
|
const TWDict& sd = (const TWDict&)src;
|
|
for (long i = 0; i < sd.GetLength(); i++)
|
|
{
|
|
const TWDictItem *pItem0 = sd.GetAt(i);
|
|
|
|
for (MoveToFirst(); !IsOut(); MoveToNext())
|
|
{
|
|
TWDictItem *pItem = GetCurData();
|
|
if (pItem->m_sName == pItem0->m_sName)
|
|
{
|
|
pItem->CopyData(*pItem0);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
TWDictItem* TWDict::DynCreateItem(int type)
|
|
{
|
|
switch(type)
|
|
{
|
|
case TYPE_WDictItem:
|
|
return new TWDictItem;
|
|
case TYPE_WDict:
|
|
return new TWDict;
|
|
case TYPE_WBoolItem:
|
|
return new TWBoolItem;
|
|
case TYPE_WCharItem:
|
|
return new TWCharItem;
|
|
case TYPE_WLongItem:
|
|
return new TWLongItem;
|
|
case TYPE_WDoubleItem:
|
|
return new TWDoubleItem;
|
|
case TYPE_WCStringItem:
|
|
return new TWCStringItem;
|
|
case TYPE_WSelectItem:
|
|
return new TWSelectItem;
|
|
default:
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
void TWDict::saveToJson(WValue & v)
|
|
{
|
|
TWDictItem::saveToJson(v);
|
|
|
|
WValue arr;
|
|
arr.SetArray();
|
|
for (MoveToFirst(); !IsOut(); MoveToNext())
|
|
{
|
|
TWDictItem &Item = GetCurPData();
|
|
WValue vv;
|
|
vv.SetObject();
|
|
Item.saveToJson(vv);
|
|
arr.PushBack(vv, getJsonAllocator());
|
|
}
|
|
v.AddMember(StringRef(_T("datas")), arr, getJsonAllocator());
|
|
}
|
|
|
|
void TWDict::loadByJson(const WValue &v)
|
|
{
|
|
TWDictItem::loadByJson(v);
|
|
|
|
Clear();
|
|
|
|
int type(-1);
|
|
MCIt it = v.FindMember(_T("datas"));
|
|
if (it != v.MemberEnd() && it->value.IsArray())
|
|
{
|
|
CArr ar = it->value.GetArray();
|
|
for (size_t i = 0; i < ar.Size(); ++i)
|
|
{
|
|
const WValue &vv = ar[i];
|
|
MCIt it = vv.FindMember(_T("type"));
|
|
if (it != vv.MemberEnd())
|
|
{
|
|
type = it->value.GetInt();
|
|
TWDictItem *pItem = DynCreateItem(type);
|
|
if (pItem)
|
|
{
|
|
pItem->loadByJson(vv);
|
|
AddTail(pItem);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |