Files
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

572 lines
9.5 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);
}
}
}
}
}