#ifndef __INC_METIN_II_GROUP_TEXT_PARSE_TREE_H__ #define __INC_METIN_II_GROUP_TEXT_PARSE_TREE_H__ #include #include #include "file_loader.h" #include typedef std::map TTokenVectorMap; typedef std::map TMapNameToIndex; class CGroupNode { public: class CGroupNodeRow { public: CGroupNodeRow(CGroupNode* pGroupNode, TTokenVector& vec_values); virtual ~CGroupNodeRow(); template bool GetValue(const std::string & stColKey, OUT T& value) const; template bool GetValue(int idx, OUT T& value) const; int GetSize() const; private: CGroupNode* m_pOwnerGroupNode; TTokenVector m_vec_values; }; public: CGroupNode(); virtual ~CGroupNode(); bool Load(const char * c_szFileName); const char * GetFileName(); DWORD GetChildNodeCount(); bool SetChildNode(const char * c_szKey, CGroupNode* pChildNode); CGroupNode* GetChildNode(const std::string & c_rstrKey) const; std::string GetNodeName() const; bool IsToken(const std::string & c_rstrKey) const; int GetRowCount(); template bool GetValue(size_t i, const std::string & c_rstrColKey, T& tValue) const; // n¹ø°(map¿¡ µé¾îÀÖ´Â ¼ø¼­ÀÏ »Ó, txtÀÇ ¼ø¼­¿Í´Â °ü°è ¾øÀ½) rowÀÇ Æ¯Á¤ Ä÷³ÀÇ °ªÀ» ¹ÝȯÇÏ´Â ÇÔ¼ö. // ÀÌÁúÀûÀ̱ä ÇÏÁö¸¸, ÆíÀǸ¦ À§ÇÑ ÇÔ¼ö. template bool GetValue(const std::string & c_rstrRowKey, const std::string & c_rstrColKey, T& tValue) const; template bool GetValue(const std::string & c_rstrRowKey, int index, T& tValue) const; bool GetRow(const std::string & c_rstrKey, OUT const CGroupNodeRow ** ppRow) const; // Âü°í·Î, idx¶û txt¿¡ ¾²¿©Áø ¼ø¼­¶û °ü°è ¾øÀ½. bool GetRow(int idx, OUT const CGroupNodeRow ** ppRow) const; bool GetGroupRow(const std::string& stGroupName, const std::string& stRow, OUT const CGroupNode::CGroupNodeRow ** ppRow) const; template bool GetGroupValue(const std::string& stGroupName, const std::string& stRow, int iCol, OUT T& tValue) const; template bool GetGroupValue(const std::string& stGroupName, const std::string& stRow, const std::string& stCol, OUT T& tValue) const; int GetColumnIndexFromName(const std::string& stName) const; private: typedef std::map TMapGroup; typedef std::map TMapRow; TMapGroup m_mapChildNodes; std::string strGroupName; TMapNameToIndex m_map_columnNameToIndex; TMapRow m_map_rows; friend class CGroupTextParseTreeLoader; }; class CGroupTextParseTreeLoader { public: CGroupTextParseTreeLoader(); virtual ~CGroupTextParseTreeLoader(); bool Load(const char * c_szFileName); const char * GetFileName(); CGroupNode* GetGroup(const char * c_szGroupName); private: bool LoadGroup(CGroupNode * pGroupNode); CGroupNode * m_pRootGroupNode; std::string m_strFileName; DWORD m_dwcurLineIndex; CMemoryTextFileLoader m_fileLoader; }; template bool from_string(OUT T& t, IN const std::string& s) { std::istringstream iss(s); return !(iss >> t).fail(); } template <> inline bool from_string (OUT BYTE& t, IN const std::string& s) { std::istringstream iss(s); int temp; bool b = !(iss >> temp).fail(); t = (BYTE)temp; return b; } template bool CGroupNode::GetValue(size_t i, const std::string & c_rstrColKey, T& tValue) const { if (i > m_map_rows.size()) return false; TMapRow::const_iterator row_it = m_map_rows.begin(); std::advance(row_it, i); itertype(m_map_columnNameToIndex) col_idx_it = m_map_columnNameToIndex.find(c_rstrColKey); if (m_map_columnNameToIndex.end() == col_idx_it) { return false; } int index = col_idx_it->second; if (row_it->second.GetSize() <= index) { return false; } return row_it->second.GetValue(index, tValue); } template bool CGroupNode::GetValue(const std::string & c_rstrRowKey, const std::string & c_rstrColKey, T& tValue) const { TMapRow::const_iterator row_it = m_map_rows.find(c_rstrRowKey); if (m_map_rows.end() == row_it) { return false; } itertype(m_map_columnNameToIndex) col_idx_it = m_map_columnNameToIndex.find(c_rstrColKey); if (m_map_columnNameToIndex.end() == col_idx_it) { return false; } int index = col_idx_it->second; if (row_it->second.GetSize() <= index) { return false; } return row_it->second.GetValue(index, tValue); } template bool CGroupNode::GetValue(const std::string & c_rstrRowKey, int index, T& tValue) const { TMapRow::const_iterator row_it = m_map_rows.find(c_rstrRowKey); if (m_map_rows.end() == row_it) { return false; } if (row_it->second.GetSize() <= index) { return false; } return row_it->second.GetValue(index, tValue); } template bool CGroupNode::GetGroupValue(const std::string& stGroupName, const std::string& stRow, int iCol, OUT T& tValue) const { CGroupNode* pChildGroup = GetChildNode(stGroupName); if (NULL != pChildGroup) { if (pChildGroup->GetValue(stRow, iCol, tValue)) return true; } // default groupÀ» »ìÆ캽. pChildGroup = GetChildNode("default"); if (NULL != pChildGroup) { if (pChildGroup->GetValue(stRow, iCol, tValue)) return true; } return false; } template bool CGroupNode::GetGroupValue(const std::string& stGroupName, const std::string& stRow, const std::string& stCol, OUT T& tValue) const { CGroupNode* pChildGroup = GetChildNode(stGroupName); if (NULL != pChildGroup) { if (pChildGroup->GetValue(stRow, stCol, tValue)) return true; } // default groupÀ» »ìÆ캽. pChildGroup = GetChildNode("default"); if (NULL != pChildGroup) { if (pChildGroup->GetValue(stRow, stCol, tValue)) return true; } return false; } template bool CGroupNode::CGroupNodeRow::GetValue(const std::string & stColKey, OUT T& value) const { int idx = m_pOwnerGroupNode->GetColumnIndexFromName(stColKey); if (idx < 0 || idx >= m_vec_values.size()) return false; return from_string(value, m_vec_values[idx]); } template bool CGroupNode::CGroupNodeRow::GetValue(int idx, OUT T& value) const { if (idx < 0 || idx >= m_vec_values.size()) return false; return from_string(value, m_vec_values[idx]); } #endif