forked from metin2/client
270 lines
6.4 KiB
C++
270 lines
6.4 KiB
C++
#include "StdAfx.h"
|
|
#include <string.h>
|
|
#include "../eterBase/TempFile.h"
|
|
|
|
#include "PropertyManager.h"
|
|
#include "Property.h"
|
|
/*
|
|
* CProperty 파일 포맷
|
|
*
|
|
* 0 ~ 4 bytes: fourcc
|
|
* 5 ~ 6 bytes: \r\n
|
|
*
|
|
* 그 이후의 바이트들은 텍스트 파일 로더와 같은 구조
|
|
*/
|
|
CProperty::CProperty(const char * c_pszFileName) : mc_pFileName(NULL), m_dwCRC(0)
|
|
{
|
|
m_stFileName = c_pszFileName;
|
|
StringPath(m_stFileName);
|
|
|
|
mc_pFileName = strrchr(m_stFileName.c_str(), '/');
|
|
|
|
if (!mc_pFileName)
|
|
mc_pFileName = m_stFileName.c_str();
|
|
else
|
|
++mc_pFileName;
|
|
}
|
|
|
|
CProperty::~CProperty()
|
|
{
|
|
}
|
|
|
|
DWORD CProperty::GetCRC()
|
|
{
|
|
return m_dwCRC;
|
|
}
|
|
|
|
const char * CProperty::GetFileName()
|
|
{
|
|
return (m_stFileName.c_str());
|
|
}
|
|
|
|
bool CProperty::GetString(const char * c_pszKey, const char ** c_ppString)
|
|
{
|
|
std::string stTempKey = c_pszKey;
|
|
stl_lowers(stTempKey);
|
|
CTokenVectorMap::iterator it = m_stTokenMap.find(stTempKey.c_str());
|
|
|
|
// printf("GetString %s %d\n", stTempKey.c_str(), m_stTokenMap.size());
|
|
|
|
if (m_stTokenMap.end() == it)
|
|
return false;
|
|
|
|
*c_ppString = it->second[0].c_str();
|
|
return true;
|
|
}
|
|
|
|
DWORD CProperty::GetSize()
|
|
{
|
|
return m_stTokenMap.size();
|
|
}
|
|
|
|
bool CProperty::GetVector(const char * c_pszKey, CTokenVector & rTokenVector)
|
|
{
|
|
std::string stTempKey = c_pszKey;
|
|
stl_lowers(stTempKey);
|
|
CTokenVectorMap::iterator it = m_stTokenMap.find(stTempKey.c_str());
|
|
|
|
if (m_stTokenMap.end() == it)
|
|
return false;
|
|
|
|
// NOTE : 튕김 현상 발견
|
|
// std::copy(rTokenVector.begin(), it->second.begin(), it->second.end());
|
|
// NOTE : 레퍼런스에는 이런 식으로 하게끔 되어 있음
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// template <class InputIterator, class OutputIterator>
|
|
// OutputIterator copy(InputIterator first, InputIterator last,
|
|
// OutputIterator result);
|
|
//
|
|
// vector<int> V(5);
|
|
// iota(V.begin(), V.end(), 1);
|
|
// list<int> L(V.size());
|
|
// copy(V.begin(), V.end(), L.begin());
|
|
// assert(equal(V.begin(), V.end(), L.begin()));
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// 헌데 그래도 튕김. - [levites]
|
|
// std::copy(it->second.begin(), it->second.end(), rTokenVector.begin());
|
|
|
|
// 결국 이렇게.. - [levites]
|
|
// 현재 사용하는 곳 : WorldEditor/Dialog/MapObjectPropertyPageBuilding.cpp
|
|
CTokenVector & rSourceTokenVector = it->second;
|
|
CTokenVector::iterator itor = rSourceTokenVector.begin();
|
|
for (; itor != rSourceTokenVector.end(); ++itor)
|
|
{
|
|
rTokenVector.push_back(*itor);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void CProperty::PutString(const char * c_pszKey, const char * c_pszString)
|
|
{
|
|
std::string stTempKey = c_pszKey;
|
|
stl_lowers(stTempKey);
|
|
|
|
// 이미 있는걸 지움
|
|
CTokenVectorMap::iterator itor = m_stTokenMap.find(stTempKey);
|
|
|
|
if (itor != m_stTokenMap.end())
|
|
m_stTokenMap.erase(itor);
|
|
|
|
CTokenVector tokenVector;
|
|
tokenVector.push_back(c_pszString);
|
|
|
|
m_stTokenMap.insert(CTokenVectorMap::value_type(stTempKey, tokenVector));
|
|
}
|
|
|
|
void CProperty::PutVector(const char * c_pszKey, const CTokenVector & c_rTokenVector)
|
|
{
|
|
std::string stTempKey = c_pszKey;
|
|
stl_lowers(stTempKey);
|
|
|
|
m_stTokenMap.insert(CTokenVectorMap::value_type(stTempKey, c_rTokenVector));
|
|
}
|
|
|
|
void GetTimeString(char * str, time_t ct)
|
|
{
|
|
struct tm tm;
|
|
tm = *localtime(&ct);
|
|
|
|
_snprintf(str, 15, "%04d%02d%02d%02d%02d%02d",
|
|
tm.tm_year + 1900,
|
|
tm.tm_mon + 1,
|
|
tm.tm_mday,
|
|
tm.tm_hour,
|
|
tm.tm_min,
|
|
tm.tm_sec);
|
|
}
|
|
|
|
bool CProperty::Save(const char * c_pszFileName)
|
|
{
|
|
CTempFile file;
|
|
|
|
DWORD fourcc = MAKEFOURCC('Y', 'P', 'R', 'T');
|
|
file.Write(&fourcc, sizeof(DWORD));
|
|
file.Write("\r\n", 2);
|
|
|
|
if (0 == m_stCRC.length())
|
|
{
|
|
char szCRC[MAX_PATH + 16 + 1];
|
|
|
|
GetTimeString(szCRC, time(0));
|
|
strcpy(szCRC + strlen(szCRC), c_pszFileName);
|
|
|
|
m_dwCRC = CPropertyManager::Instance().GetUniqueCRC(szCRC);
|
|
_snprintf(szCRC, sizeof(szCRC), "%u", m_dwCRC);
|
|
|
|
m_stCRC.assign(szCRC);
|
|
}
|
|
|
|
file.Write(m_stCRC.c_str(), m_stCRC.length());
|
|
file.Write("\r\n", 2);
|
|
|
|
CTokenVectorMap::iterator itor = m_stTokenMap.begin();
|
|
char buf[4096 + 1];
|
|
|
|
while (itor != m_stTokenMap.end())
|
|
{
|
|
CTokenVector & tokenVector = itor->second;
|
|
|
|
int len = _snprintf(buf, sizeof(buf), "%s\t", itor->first.c_str());
|
|
file.Write(buf, len);
|
|
|
|
for (DWORD i = 0; i < tokenVector.size(); ++i)
|
|
{
|
|
len = _snprintf(buf, sizeof(buf), "\t\"%s\"", tokenVector[i].c_str());
|
|
file.Write(buf, len);
|
|
}
|
|
|
|
file.Write("\r\n", 2);
|
|
++itor;
|
|
}
|
|
|
|
file.Close();
|
|
return CPropertyManager::Instance().Put(c_pszFileName, file.GetFileName());
|
|
}
|
|
|
|
bool CProperty::ReadFromMemory(const void * c_pvData, int iLen, const char * c_pszFileName)
|
|
{
|
|
const char * pcData = (const char *) c_pvData;
|
|
|
|
if (*(DWORD *) pcData != MAKEFOURCC('Y', 'P', 'R', 'T'))
|
|
return false;
|
|
|
|
pcData += sizeof(DWORD);
|
|
|
|
if (*pcData != '\r' || *(pcData + 1) != '\n')
|
|
{
|
|
TraceError("CProperty::ReadFromMemory: File format error after FourCC: %s\n", c_pszFileName);
|
|
return false;
|
|
}
|
|
|
|
pcData += 2;
|
|
|
|
CTokenVector stTokenVector;
|
|
/*
|
|
char szTimeStamp[64];
|
|
memcpy(szTimeStamp, pcData, 14);
|
|
szTimeStamp[14] = '\0';
|
|
pcData += 14;
|
|
|
|
if (*pcData != '\r' || *(pcData + 1) != '\n')
|
|
{
|
|
TraceError("CProperty::ReadFromMemory: File format error after TimeStamp: %s\n", c_pszFileName);
|
|
return false;
|
|
}
|
|
|
|
std::string m_stTimeStamp;
|
|
|
|
m_stTimeStamp = szTimeStamp;
|
|
|
|
int iTimeStampLen = 14 + _snprintf(szTimeStamp + 14, 64 - 14, "%s", mc_pFileName);
|
|
m_dwCRC = GetCRC32(szTimeStamp, iTimeStampLen);
|
|
|
|
char tmp[64];
|
|
sprintf(tmp, "%u", m_dwCRC);
|
|
m_stCRC.assign(tmp);
|
|
|
|
CMemoryTextFileLoader textFileLoader;
|
|
textFileLoader.Bind(iLen - (sizeof(DWORD) + 2 + 14 + 2), pcData);
|
|
|
|
for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i)
|
|
{
|
|
if (!textFileLoader.SplitLine(i, &stTokenVector))
|
|
continue;
|
|
|
|
stl_lowers(stTokenVector[0]);
|
|
std::string stKey = stTokenVector[0];
|
|
|
|
stTokenVector.erase(stTokenVector.begin());
|
|
PutVector(stKey.c_str(), stTokenVector);
|
|
}
|
|
return true;
|
|
*/
|
|
CMemoryTextFileLoader textFileLoader;
|
|
textFileLoader.Bind(iLen - (sizeof(DWORD) + 2), pcData);
|
|
|
|
m_stCRC = textFileLoader.GetLineString(0);
|
|
m_dwCRC = atoi(m_stCRC.c_str());
|
|
|
|
for (DWORD i = 1; i < textFileLoader.GetLineCount(); ++i)
|
|
{
|
|
if (!textFileLoader.SplitLine(i, &stTokenVector))
|
|
continue;
|
|
|
|
stl_lowers(stTokenVector[0]);
|
|
std::string stKey = stTokenVector[0];
|
|
|
|
stTokenVector.erase(stTokenVector.begin());
|
|
PutVector(stKey.c_str(), stTokenVector);
|
|
}
|
|
|
|
//Tracef("Property: %s\n", c_pszFileName);
|
|
return true;
|
|
}
|
|
|
|
void CProperty::Clear()
|
|
{
|
|
m_stTokenMap.clear();
|
|
}
|