forked from metin2/server
260 lines
5.5 KiB
C++
260 lines
5.5 KiB
C++
#include "stdafx.h"
|
||
#include <common/stl.h>
|
||
#include "group_text_parse_tree.h"
|
||
|
||
CGroupTextParseTreeLoader::CGroupTextParseTreeLoader()
|
||
: m_dwcurLineIndex(0), m_pRootGroupNode(NULL)
|
||
{
|
||
}
|
||
|
||
CGroupTextParseTreeLoader::~CGroupTextParseTreeLoader()
|
||
{
|
||
if (NULL != m_pRootGroupNode)
|
||
delete m_pRootGroupNode;
|
||
}
|
||
|
||
const char * CGroupTextParseTreeLoader::GetFileName()
|
||
{
|
||
return m_strFileName.c_str();
|
||
}
|
||
|
||
bool CGroupTextParseTreeLoader::Load(const char * c_szFileName)
|
||
{
|
||
m_strFileName = c_szFileName;
|
||
|
||
m_dwcurLineIndex = 0;
|
||
|
||
FILE* fp = fopen(c_szFileName, "rb");
|
||
|
||
if (NULL == fp)
|
||
return false;
|
||
|
||
fseek(fp, 0L, SEEK_END);
|
||
const size_t fileSize = ftell(fp);
|
||
fseek(fp, 0, SEEK_SET);
|
||
|
||
char * pData = M2_NEW char[fileSize];
|
||
fread(pData, fileSize, 1, fp);
|
||
fclose(fp);
|
||
|
||
m_fileLoader.Bind(fileSize, pData);
|
||
M2_DELETE_ARRAY(pData);
|
||
|
||
if (NULL != m_pRootGroupNode)
|
||
{
|
||
delete m_pRootGroupNode;
|
||
}
|
||
|
||
m_pRootGroupNode = new CGroupNode();
|
||
if (!LoadGroup(m_pRootGroupNode))
|
||
{
|
||
delete m_pRootGroupNode;
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
bool CGroupTextParseTreeLoader::LoadGroup(CGroupNode * pGroupNode)
|
||
{
|
||
TTokenVector stTokenVector;
|
||
for (; m_dwcurLineIndex < m_fileLoader.GetLineCount(); ++m_dwcurLineIndex)
|
||
{
|
||
if (!m_fileLoader.SplitLine(m_dwcurLineIndex, &stTokenVector))
|
||
continue;
|
||
|
||
stl_lowers(stTokenVector[0]);
|
||
|
||
if ('{' == stTokenVector[0][0])
|
||
continue;
|
||
|
||
if ('}' == stTokenVector[0][0])
|
||
break;
|
||
|
||
// Group
|
||
if (0 == stTokenVector[0].compare("group"))
|
||
{
|
||
if (2 != stTokenVector.size())
|
||
{
|
||
sys_err("Invalid group syntax token size: %u != 2 (DO NOT SPACE IN NAME)", stTokenVector.size());
|
||
for (unsigned int i = 0; i < stTokenVector.size(); ++i)
|
||
sys_err(" %u %s", i, stTokenVector[i].c_str());
|
||
exit(1);
|
||
continue;
|
||
}
|
||
|
||
CGroupNode * pNewNode = new CGroupNode();
|
||
|
||
pNewNode->strGroupName = stTokenVector[1];
|
||
stl_lowers(pNewNode->strGroupName);
|
||
|
||
pGroupNode->SetChildNode(pNewNode->strGroupName.c_str(), pNewNode);
|
||
|
||
++m_dwcurLineIndex;
|
||
|
||
LoadGroup(pNewNode);
|
||
}
|
||
// Column Names
|
||
else if (0 == stTokenVector[0].compare("#--#"))
|
||
{
|
||
for (int i = 1; i < stTokenVector.size(); i++)
|
||
{
|
||
stl_lowers(stTokenVector[i]);
|
||
pGroupNode->m_map_columnNameToIndex.insert(TMapNameToIndex::value_type (stTokenVector[i], i - 1));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
std::string key = stTokenVector[0];
|
||
|
||
if (1 == stTokenVector.size())
|
||
{
|
||
sys_err("CGroupTextParseTreeLoader::LoadGroup : must have a value (filename: %s line: %d key: %s)",
|
||
m_strFileName.c_str(),
|
||
m_dwcurLineIndex,
|
||
key.c_str());
|
||
break;
|
||
}
|
||
|
||
stTokenVector.erase(stTokenVector.begin());
|
||
pGroupNode->m_map_rows.insert(std::make_pair(key, CGroupNode::CGroupNodeRow(pGroupNode, stTokenVector)));
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
CGroupNode* CGroupTextParseTreeLoader::GetGroup(const char * c_szGroupName)
|
||
{
|
||
if (NULL == m_pRootGroupNode)
|
||
return NULL;
|
||
return m_pRootGroupNode->GetChildNode(c_szGroupName);
|
||
}
|
||
|
||
CGroupNode::CGroupNode()
|
||
{
|
||
}
|
||
|
||
CGroupNode::~CGroupNode()
|
||
{
|
||
for (TMapGroup::iterator it = m_mapChildNodes.begin(); it != m_mapChildNodes.end(); it++)
|
||
{
|
||
delete it->second;
|
||
}
|
||
}
|
||
|
||
DWORD CGroupNode::GetChildNodeCount()
|
||
{
|
||
return m_mapChildNodes.size();
|
||
}
|
||
|
||
bool CGroupNode::SetChildNode(const char * c_szKey, CGroupNode* pChildGroup)
|
||
{
|
||
if (NULL == pChildGroup)
|
||
{
|
||
m_mapChildNodes.erase(c_szKey);
|
||
return true;
|
||
}
|
||
TMapGroup::iterator it = m_mapChildNodes.find(c_szKey);
|
||
if (it != m_mapChildNodes.end())
|
||
return false;
|
||
|
||
m_mapChildNodes.insert (TMapGroup::value_type (c_szKey, pChildGroup));
|
||
|
||
return true;
|
||
}
|
||
|
||
CGroupNode* CGroupNode::GetChildNode(const std::string & c_rstrKey) const
|
||
{
|
||
TMapGroup::const_iterator it = m_mapChildNodes.find(c_rstrKey);
|
||
if (it != m_mapChildNodes.end())
|
||
return it->second;
|
||
else
|
||
return NULL;
|
||
}
|
||
|
||
std::string CGroupNode::GetNodeName() const
|
||
{
|
||
return strGroupName;
|
||
}
|
||
|
||
bool CGroupNode::IsToken(const std::string & c_rstrKey) const
|
||
{
|
||
return m_map_rows.end() != m_map_rows.find(c_rstrKey);
|
||
}
|
||
|
||
int CGroupNode::GetRowCount()
|
||
{
|
||
return m_map_rows.size();
|
||
}
|
||
|
||
bool CGroupNode::GetRow(const std::string & c_rstrRowKey, OUT const CGroupNode::CGroupNodeRow ** ppRow) const
|
||
{
|
||
TMapRow::const_iterator row_it = m_map_rows.find(c_rstrRowKey);
|
||
if (m_map_rows.end() == row_it)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
*ppRow = &row_it->second;
|
||
|
||
return true;
|
||
}
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, idx<64><78> txt<78><74> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||
bool CGroupNode::GetRow(int idx, OUT const CGroupNode::CGroupNodeRow ** ppRow) const
|
||
{
|
||
if (idx >= m_map_rows.size())
|
||
return false;
|
||
|
||
TMapRow::const_iterator row_it = m_map_rows.begin();
|
||
|
||
std::advance(row_it, idx);
|
||
|
||
*ppRow = &row_it->second;
|
||
|
||
return true;
|
||
}
|
||
|
||
bool CGroupNode::GetGroupRow(const std::string& stGroupName, const std::string& stRow, OUT const CGroupNode::CGroupNodeRow ** ppRow) const
|
||
{
|
||
CGroupNode* pChildGroup = GetChildNode(stGroupName);
|
||
if (NULL != pChildGroup)
|
||
{
|
||
if (pChildGroup->GetRow(stRow, ppRow))
|
||
return true;
|
||
}
|
||
// default group<75><70> <20><><EFBFBD>캽.
|
||
pChildGroup = GetChildNode("default");
|
||
if (NULL != pChildGroup)
|
||
{
|
||
if (pChildGroup->GetRow(stRow, ppRow))
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
int CGroupNode::GetColumnIndexFromName(const std::string& stName) const
|
||
{
|
||
TMapNameToIndex::const_iterator it = m_map_columnNameToIndex.find(stName);
|
||
if (m_map_columnNameToIndex.end() == it)
|
||
return -1;
|
||
else
|
||
return it->second;
|
||
}
|
||
|
||
CGroupNode::CGroupNodeRow::CGroupNodeRow(CGroupNode* pGroupNode, TTokenVector& vec_values)
|
||
{
|
||
m_pOwnerGroupNode = pGroupNode;
|
||
m_vec_values.clear();
|
||
std::copy(vec_values.begin(), vec_values.end(), std::back_inserter(m_vec_values));
|
||
}
|
||
|
||
CGroupNode::CGroupNodeRow::~CGroupNodeRow()
|
||
{
|
||
}
|
||
|
||
int CGroupNode::CGroupNodeRow::GetSize() const
|
||
{
|
||
return m_vec_values.size();
|
||
}
|