- °³¿ä
- ¼Ò½º
- YamlTree.h
- YamlTree.cpp
- »ùÇÃ
- ÁÖÀÇ »çÇ×
- YAML ¹®¹ý °Ë»ç±â
1 °³¿ä
ÁöÀúºÐÇÑ XML ¼³Á¤ ÆÄÀϵéÀ» ¾²´Ù°¡ ´ä´äÇÑ ¸¶À½¿¡ °á±¹ ÆÄ¼¸¦ ¸¸µé¾ú´Ù. YAML ½ºÆåÀÌ ¿ö³« ¹æ´ëÇϳªº¸´Ï, ¿Ïº®ÇÑ C/C++ ÆÄ¼¸¦ ¸¸µé´Ù°¡´Â ¸î´ÞÀÌ °É¸±Áö ¸ô¶ó¼, ±×³É ¾µ¸¸ÇÏ´Ù°í ÆÇ´ÜµÇ´Â ±â´É¸¸ °ñ¶ó¼ ¸¸µé¾ú´Ù.
- ±¸ÇöÇÑ ±â´É ¹× Ư¡
- ±âº»ÀûÀÎ scalar, sequence, mapping Áö¿ø (¸ðµç ½ºÄ®¶ó´Â ¹®ÀÚ¿·Î ó¸®ÇÑ´Ù.)
- Block scalar ¹× folded scalar Áö¿ø
- Anchor & alias Áö¿ø
- ÁÖ¼® ÀоîµéÀ̱â/¾²±â Áö¿ø
- D3DXVECTOR2, D3DXVECTOR3, D3DXVECTOR4, D3DXQUATERNION, D3DXCOLOR Áö¿ø.
ÀϹÝÀûÀ¸·Î »ý°¢ÇÏÀÚ¸é µé¾î°¡¾ßÇÒ ±â´ÉÀº ¾Æ´Ï´Ù¸¸, ÀÏ´ÜÀº "°ÔÀÓ" ÇÁ·Î±×·¥¿¡ ¾²´Â °Å´Ù º¸´Ï...
- ÇÊ¿äÇÏ´Ù°í »ý°¢ÇÏ´Â ±â´É (±¸Çö ¿¹Á¤?)
- Inline flow mapping
- Escape character ¶Ç´Â verbatim ó¸®
- Document start/end marker
- Binary scalar
- À¯´ÏÄÚµå/ÀÎÄÚµù Áö¿ø
±âº»ÀûÀÎ ±¸Çö ¹æ½ÄÀº XML ÂÊÀÇ DOM ÆÄ¼¸¦ »ý°¢ÇÏ¸é µÈ´Ù. Áï ¹®¼¸¦ Åëä·Î ·ÎµåÇØ¼ ¸Þ¸ð¸® »ó¿¡ Æ®¸® ÇüÅ·Π±¸¼ºÇÏ´Â ÆÄ¼ÀÌ´Ù.
2 ¼Ò½º
////////////////////////////////////////////////////////////////////////////////
/// \file YamlTree.h
/// \author excel96
/// \date 2006.4.21
////////////////////////////////////////////////////////////////////////////////
#ifndef __YAMLTREE_H__
#define __YAMLTREE_H__
#include <iosfwd>
#include <map>
#include <string>
#include <vector>
////////////////////////////////////////////////////////////////////////////////
/// \class cYamlTree
/// \brief °£´ÜÇÑ YAML ÆÄ¼. XML ÂÊÀÇ DOM ÆÄ¼¸¦ »ý°¢ÇÏ¸é µÈ´Ù. Áï ¹®¼¸¦
/// Åëä·Î ·ÎµåÇØ¼ ¸Þ¸ð¸® »ó¿¡ Æ®¸® ÇüÅ·Π±¸¼ºÇÏ´Â ÆÄ¼ÀÌ´Ù.
///
/// XML ÆÄÀÏÀÌ ³Ê¹« ÁöÀúºÐÇÑ °æÇâÀÌ ÀÖ¾î, ´ë¾ÈÀ» ã´Ù°¡ YAMLÀ̶ó´Â °ÍÀ» ¾Ë°Ô
/// µÇ¾ú´Ù. ¹®¹ýÀÌ ±ò²ûÇϱâ´Â Çѵ¥, C/C++ ÆÄ¼°¡ ÇöÀç Á¸ÀçÇÏÁö ¾Ê¾Æ¼ ´ëÃæ
/// ¾²´Â ±â´Éµé¸¸ ¸ð¾Æ¼ Çѹø ¸¸µé¾îºÃ´Ù. ÇöÀç Áö¿øÇÏ´Â ±â´ÉÀ» º¸ÀÚ¸é ´ÙÀ½°ú
/// °°´Ù.
///
/// - ±âº»ÀûÀÎ scalar, sequence, mapping Áö¿ø
/// - Block scalar ¹× folded scalar Áö¿ø
/// - Anchor & alias Áö¿ø
/// - ¶óÀÎ ÁÖ¼® Áö¿ø
///
/// ÀÚ½Ä ³ëµå´Â ¸Ê ÇüÅ ¶Ç´Â ¹è¿ ÇüÅ·Π¾×¼¼½ºÇÒ ¼ö ÀÖ´Ù. µÑÀ» È¥¿ëÇÒ ¼ö´Â
/// ¾ø´Ù. ±âº»ÀûÀ¸·Î´Â Ű ¹®ÀÚ¿À» ÀÌ¿ëÇØ ¸Ê ÇüÅ·ΠÀÚ½Ä ³ëµåµéÀ» µÎ°Ô µÈ´Ù.
/// ÀÌ´Â °°Àº À̸§(key)ÀÇ ÀÚ½Ä ³ëµå°¡ 2°³ ÀÌ»ó ÀÖ´Â °æ¿ì, ±× Áß¿¡ Çϳª¸¸
/// ¼±ÅõÊÀ» ÀǹÌÇÑ´Ù. Ruby¿¡ ÀÖ´Â YAML ÆÄ¼ °°Àº °æ¿ì¿¡´Â Á¦ÀÏ ¸¶Áö¸·¿¡ µé¾î¿Â
/// ÀÚ½Ä ³ëµå¸¦ ¼±ÅÃÇÑ´Ù. ÇÏÁö¸¸ ¿©±â¼´Â Á¦ÀÏ Ã¹¹øÂ°·Î µé¾î¿Â ÀÚ½Ä ³ëµå¸¦
/// ¼±ÅÃÇϰí, ±× ´ÙÀ½ µé¾î¿À´Â ³ëµå´Â »èÁ¦ÇØ ¹ö¸®´Â ¹æ½ÄÀ» ÅÃÇß´Ù. ¹è¿ ÇüÅ·Î
/// ÀÚ½ÄÀ» µÎ±â À§Çؼ´Â '-' ¿¬»êÀÚ¸¦ ÀÌ¿ëÇØ¾ß ÇÑ´Ù. ÀÚ¼¼ÇÑ °ÍÀº ¿ª½Ã YAML
/// ¹®¹ýÀ» Âü°í.
///
/// \todo Verbatim 󸮰¡ ÇÊ¿äÇÏ´Ù.
////////////////////////////////////////////////////////////////////////////////
class cYamlTree
{
public:
// ½ºÄ®¶óÀÇ Á¾·ù
enum ScalarType
{
NORMAL_SCALAR, ///< ÀϹÝÀûÀÎ ½ºÄ®¶ó
BLOCK_SCALAR, ///< key : | ÇüÅÂÀÇ °ª
FOLDED_SCALAR ///< key : > ÇüÅÂÀÇ °ª
};
// ÀÚ½Ä ³ëµå Ⱦ´ÜÀ» À§ÇÑ Å¸ÀÔ ¼±¾ð
typedef std::map<std::string, cYamlTree*>::iterator iterator;
typedef std::map<std::string, cYamlTree*>::const_iterator const_iterator;
typedef std::vector<std::string> SCALARS;
// ¿¡·¯ ÅëÁö ÇÔ¼ö ŸÀÔ ¼±¾ð
typedef void (*PFN_ERROR_HANDLER)(const char* errormsg);
protected:
enum ChildType
{
CHILD_MAPPED, ///< ÀÚ½Ä ³ëµåÀÇ Ä÷º¼ÇÀ¸·Î ¸ÊÀ» »ç¿ëÇÑ´Ù.
CHILD_SEQNENTIAL, ///< ÀÚ½Ä ³ëµåÀÇ Ä÷º¼ÇÀ¸·Î ¹è¿À» »ç¿ëÇÑ´Ù.
CHILD_UNKNOWN ///< ³»ºÎÀûÀ¸·Î »ç¿ëÇÏ´Â °ª.
};
typedef std::vector<cYamlTree*> SEQUENCE;
typedef std::map<std::string, cYamlTree*> MAPPING;
std::string m_Key; ///< Ű
std::string m_Value; ///< °ª
std::string m_Comment; ///< ÄÚ¸àÆ®
ScalarType m_ScalarType; ///< °ªÀÇ Á¾·ù
SCALARS m_Scalars; ///< ¿©·¯ Çà¿¡ °ÉÄ£ ½ºÄ®¶ó °ª
cYamlTree* m_Alias; ///< ¾ÞÄ¿ ¾Ë¸®¾Æ½º
ChildType m_ChildType; ///< ÀÚ½Ä Å¸ÀÔ (map or hash)
MAPPING m_MappedChilds; ///< ÀÚ½Ä ³ëµåµé
SEQUENCE m_SequentialChilds; ///< ÀÚ½Ä ³ëµåµé
size_t m_MaxChildKeyLength; ///< ÀÚ½Ä ³ëµåÀÇ À̸§ ±æÀÌ ÃÖ´ë°ª
static PFN_ERROR_HANDLER s_ParseErrorHandler; ///< ÆÄ½Ì ¿¡·¯ Çڵ鷯
static PFN_ERROR_HANDLER s_AccessErrorHandler; ///< ÀÏ¹Ý ¿¡·¯ Çڵ鷯
public:
/// \name »ý¼ºÀÚ
/// \{
cYamlTree();
cYamlTree(const std::string& key, const std::string& value);
cYamlTree(const std::string& key, const char* value);
cYamlTree(const std::string& key, int value);
cYamlTree(const std::string& key, float value);
cYamlTree(const std::string& key, double value);
cYamlTree(const std::string& key, bool value);
#ifdef D3DX_VERSION
cYamlTree(const std::string& key, const D3DXVECTOR2& value);
cYamlTree(const std::string& key, const D3DXVECTOR3& value);
cYamlTree(const std::string& key, const D3DXVECTOR4& value);
cYamlTree(const std::string& key, const D3DXQUATERNION& value);
cYamlTree(const std::string& key, const D3DXCOLOR& value);
#endif
/// \}
/// \brief ¼Ò¸êÀÚ
virtual ~cYamlTree();
public:
/// \name Ű ¹Ýȯ/¼³Á¤ ÇÔ¼ö
/// \{
const std::string& GetKey() const { return m_Key; }
void SetKey(const std::string& key) { m_Key = key; }
void SetKey(const char* key) { m_Key = key; }
/// \}
/// \name °ª ¹Ýȯ/¼³Á¤ ÇÔ¼ö
/// \{
const std::string& GetValue() const;
const char* GetValueAsString() const;
int GetValueAsInt() const;
float GetValueAsFloat() const;
double GetValueAsDouble() const;
bool GetValueAsBool() const;
void SetValue(const std::string& value);
void SetValue(const char* value);
void SetValue(int value);
void SetValue(float value);
void SetValue(double value);
void SetValue(bool value);
#ifdef D3DX_VERSION
D3DXVECTOR2 GetValueAsVector2() const;
D3DXVECTOR3 GetValueAsVector3() const;
D3DXVECTOR4 GetValueAsVector4() const;
D3DXQUATERNION GetValueAsQuaternion() const;
D3DXCOLOR GetValueAsColor() const;
void SetValue(const D3DXVECTOR2& value);
void SetValue(const D3DXVECTOR3& value);
void SetValue(const D3DXVECTOR4& value);
void SetValue(const D3DXQUATERNION& value);
void SetValue(const D3DXCOLOR& value);
#endif
/// \}
/// \name ÁÖ¼® ¹®ÀÚ¿ ¹Ýȯ/¼³Á¤ ÇÔ¼ö
/// \{
const std::string& GetComment() const;
void SetComment(const std::string& comment);
/// \}
/// \name °ªÀÇ Á¾·ù ¹Ýȯ/¼³Á¤ ÇÔ¼ö
/// \{
ScalarType GetScalarType() const;
void SetScalarType(ScalarType type);
/// \}
/// \name ½ºÄ®¶ó °ª ¹Ýȯ/¼³Á¤ ÇÔ¼ö
/// \{
void AddScalar(const std::string& value);
const SCALARS& GetScalars() const;
/// \}
/// \name ¾ÞÄ¿ ¾Ë¸®¾Æ½º ¹Ýȯ ¹× ¼³Á¤
/// \{
cYamlTree* GetAlias() const;
void SetAlias(cYamlTree* alias);
/// \}
public:
/// \brief ÀÚ½Ä ³ëµåÀÇ Á¾·ù¸¦ ¹ÝȯÇÑ´Ù.
ChildType GetChildType() const { return m_ChildType; }
/// \brief ÀÚ½Ä ³ëµå¸¦ Ãß°¡ÇÑ´Ù. Ãß°¡ÇÑ ÀÚ½Ä ³ëµå´Â ³»ºÎ¿¡¼ delete·Î
/// »èÁ¦ÇϹǷΠ¹Ýµå½Ã new¸¦ ÅëÇØ Èü¿¡´Ù »ý¼ºÇØ¾ß ÇÑ´Ù.
cYamlTree* AddChild(cYamlTree* child);
/// \brief ÇØ´çÇÏ´Â ÀÚ½Ä ³ëµå¸¦ °¡Áö°í ÀÖ´ÂÁöÀÇ ¿©ºÎ¸¦ ¹ÝȯÇÑ´Ù.
bool HasChild(const std::string& key) const;
/// \name ¹è¿(sequence) ÇüÅ·ΠÀÚ½Ä ³ëµå¸¦ ¾×¼¼½ºÇϱâ À§ÇÑ ÇÔ¼öµé
/// \{
cYamlTree* GetChild(size_t i, bool strict=true) const;
cYamlTree& operator[](size_t i);
const cYamlTree& operator[](size_t i) const;
size_t GetChildCount() const;
/// \}
/// \name ¸Ê ÇüÅ·ΠÀÚ½Ä ³ëµå¸¦ ¾×¼¼½ºÇϱâ À§ÇÑ ÇÔ¼öµé
/// \{
cYamlTree* GetChild(const std::string& key, bool strict=true) const;
cYamlTree& operator[](const std::string& key);
const cYamlTree& operator[](const std::string& key) const;
iterator BeginChild() { return m_MappedChilds.begin(); }
iterator EndChild() { return m_MappedChilds.end(); }
const_iterator BeginChild() const { return m_MappedChilds.begin(); }
const_iterator EndChild() const { return m_MappedChilds.end(); }
/// \}
public:
/// \name ÀÚ½Ä ³ëµå °ª ¹Ýȯ ÇÔ¼ö
/// \{
const char* AttrAsString(const std::string& key) const;
int AttrAsInt(const std::string& key) const;
float AttrAsFloat(const std::string& key) const;
double AttrAsDouble(const std::string& key) const;
bool AttrAsBool(const std::string& key) const;
const char* AttrAsStringSafe(const std::string& key, const char* nullValue="") const;
int AttrAsIntSafe(const std::string& key, int nullValue=-1) const;
float AttrAsFloatSafe(const std::string& key, float nullValue=-1.0f) const;
double AttrAsDoubleSafe(const std::string& key, double nullValue=-1.0) const;
bool AttrAsBoolSafe(const std::string& key, bool nullValue=false) const;
#ifdef D3DX_VERSION
D3DXVECTOR2 AttrAsVector2(const std::string& key) const;
D3DXVECTOR3 AttrAsVector3(const std::string& key) const;
D3DXVECTOR4 AttrAsVector4(const std::string& key) const;
D3DXQUATERNION AttrAsQuaternion(const std::string& key) const;
D3DXCOLOR AttrAsColor(const std::string& key) const;
D3DXVECTOR2 AttrAsVector2Safe(const std::string& key, const D3DXVECTOR2& nullValue) const;
D3DXVECTOR3 AttrAsVector3Safe(const std::string& key, const D3DXVECTOR3& nullValue) const;
D3DXVECTOR4 AttrAsVector4Safe(const std::string& key, const D3DXVECTOR4& nullValue) const;
D3DXQUATERNION AttrAsQuaternionSafe(const std::string& key, const D3DXQUATERNION& nullValue) const;
D3DXCOLOR AttrAsColorSafe(const std::string& key, const D3DXCOLOR& nullValue) const;
#endif
/// \}
/// \name ÀÚ½Ä ³ëµå °ª Ãß°¡ ÇÔ¼ö
/// \{
cYamlTree* AddAttr(const std::string& key, const std::string& value);
cYamlTree* AddAttr(const std::string& key, const char* value);
cYamlTree* AddAttr(const std::string& key, int value);
cYamlTree* AddAttr(const std::string& key, float value);
cYamlTree* AddAttr(const std::string& key, double value);
cYamlTree* AddAttr(const std::string& key, bool value);
#ifdef D3DX_VERSION
cYamlTree* AddAttr(const std::string& key, const D3DXVECTOR2& value);
cYamlTree* AddAttr(const std::string& key, const D3DXVECTOR3& value);
cYamlTree* AddAttr(const std::string& key, const D3DXVECTOR4& value);
cYamlTree* AddAttr(const std::string& key, const D3DXQUATERNION& value);
cYamlTree* AddAttr(const std::string& key, const D3DXCOLOR& value);
#endif
/// \}
public:
/// \brief ÀڽŠ¹× ¸ðµç ÀÚ½Ä ³ëµåµéÀ» ÃʱâÈÇÑ´Ù.
void Clear();
/// \brief ³»ºÎ µ¥ÀÌÅ͸¦ ¹®ÀÚ¿ ÇüÅ·Π¹ÝȯÇÑ´Ù.
std::string ToString(bool beautify=false, bool includeSelf=false) const;
public:
/// \name ¿¡·¯ ÅëÁö ÇÔ¼ö ¼³Á¤/¹Ýȯ
/// \{
static PFN_ERROR_HANDLER GetParseErrorHandler() { return s_ParseErrorHandler; }
static PFN_ERROR_HANDLER GetAccessErrorHandler() { return s_AccessErrorHandler; }
static void SetParseErrorHandler(PFN_ERROR_HANDLER handler) { s_ParseErrorHandler = handler; }
static void SetAccessErrorHandler(PFN_ERROR_HANDLER handler) { s_AccessErrorHandler = handler; }
/// \}
protected:
/// \brief ³»ºÎ µ¥ÀÌÅ͸¦ ¹®ÀÚ¿ ÇüÅ·Π¹ÝȯÇÑ´Ù.
std::string ToString(size_t indent, bool mapped, const std::string& header,
bool beautify, size_t maxKeyLength) const;
private:
/// º¹»ç »ý¼º ±ÝÁö
cYamlTree(const cYamlTree&) {}
/// ´ëÀÔ ¿¬»ê ±ÝÁö
cYamlTree& operator = (cYamlTree&) { return *this; }
};
////////////////////////////////////////////////////////////////////////////////
/// \class cYamlDocument
/// \brief cYamlTree ÃÖ»óÀ§ ³ëµå.
///
/// ½ÇÁ¦·Î ÆÄÀÏ ÀÔÃâ·ÂÀ» ´Ù·ê ¶§¿¡´Â ÀÌ Å¬·¡½º¸¦ ÀÌ¿ëÇØ¾ß ÇÑ´Ù. ÀÌ¿Í °°Àº
/// Ŭ·¡½º°¡ ÇÊ¿äÇÑ ÀÌÀ¯´Â ANCHOR Á¤º¸°¡ ¹®¼ Àüü¸¦ ÅëÇØ Àü¿ªÀ¸·Î Á¸ÀçÇϱâ
/// ¶§¹®ÀÌ´Ù. Load/Save ÇÔ¼öµµ ¾îÂ÷ÇÇ ÀÌ¿Í °°Àº Ŭ·¡½º¸¦ µû·Î µÎ°í, ÀÌ ¾È¿¡
/// ³Ö´Â °ÍÀÌ ±ò²ûÇϱâ´Â ÇÏ´Ù.
///
/// Anchor & alias °°Àº °æ¿ì, ÆÄÀÏÀ» ÀоîµéÀÏ ¶§, Áï ÀÌ¹Ì Á¸ÀçÇÏ´Â
/// anchor & alias Á¤º¸¸¦ ÀоîµéÀÌ´Â °ÍÀº º° ¹®Á¦°¡ ¾ø´Ù. ¹®Á¦´Â ±× ¹Ý´ë,
/// Áï ¸Þ¸ð¸® »ó¿¡¼ Æ®¸® ±¸Á¶¸¦ ±¸¼ºÇÑ ÈÄ, ÆÄÀÏ¿¡´Ù ¾µ ¶§´Â ÀÎÅÍÆäÀ̽º¸¦
/// ¾î¶»°Ô Á¦°øÇØ¾ß ÇÒÁö¸¦ Àß ¸ð¸£°Ú´Ù.
////////////////////////////////////////////////////////////////////////////////
class cYamlDocument : public cYamlTree
{
private:
typedef std::map<std::string, cYamlTree*> ANCHORS;
ANCHORS m_Anchors; ///< ¾ÞÄ¿ ¸ñ·Ï
std::string m_LastError; ///< ¸¶Áö¸·À¸·Î ¹ß»ýÇÑ ¿¡·¯ ¹®ÀÚ¿
public:
/// \brief »ý¼ºÀÚ
cYamlDocument();
/// \brief ¼Ò¸êÀÚ
virtual ~cYamlDocument();
public:
/// \brief ¾ÞÄ¿¸¦ Ãß°¡ÇÑ´Ù.
void AddAnchor(const std::string& name, cYamlTree* tree);
/// \brief ÇØ´çÇÏ´Â À̸§ÀÇ ¾ÞÄ¿¸¦ ¹ÝȯÇÑ´Ù.
cYamlTree* GetAnchor(const std::string& name) const;
/// \brief ¸ðµç ¾ÞÄ¿¸¦ »èÁ¦ÇÑ´Ù.
void ClearAnchors();
/// \brief ÆÄÀÏ¿¡¼ µ¥ÀÌÅ͸¦ Àоîµé¿© µ¥ÀÌÅ͸¦ ±¸¼ºÇÑ´Ù.
bool Load(const char* fileName);
/// \brief ³»ºÎ µ¥ÀÌÅ͸¦ ÆÄÀÏ¿¡´Ù ÀúÀåÇÑ´Ù.
bool Save(const char* fileName, bool beautify=false) const;
/// \brief ¸¶Áö¸·À¸·Î ¹ß»ýÇÑ ¿¡·¯ ¹®ÀÚ¿À» ¹ÝȯÇÑ´Ù.
const std::string& GetLastError() const { return m_LastError; }
};
#endif
2.2 YamlTree.cpp
////////////////////////////////////////////////////////////////////////////////
/// \file YamlTree.cpp
/// \author excel96
/// \date 2006.4.21
////////////////////////////////////////////////////////////////////////////////
#include "PCH.h"
#include "YamlTree.h"
namespace
{
const std::string YAML_WHITESPACES = " \t\r\n";
const std::string YAML_LINEFEEDS = "\r\n";
const std::string YAML_INDENT = " \t";
const char YAML_COLON = ':';
const char YAML_SHARP = '#';
const char YAML_MINUS = '-';
const char YAML_AMPERSAND = '&';
const char YAML_ASTERISK = '*';
const std::string YAML_PIPE = "|";
const std::string YAML_RIGHT_BRACKET = ">";
//const std::string YAML_DOCUMENT_HEADER = "---";
//const std::string YAML_DOCUMENT_TERMINATOR = "...";
/// ÇÑ ¶óÀο¡ ´ëÇÑ ÆÄ½Ì °á°ú
enum ParseResult
{
RESULT_NORMAL,
RESULT_EMPTY,
};
/// ¿©·¯ ¶óÀο¡ °ÉÄ£ µ¥ÀÌÅ͸¦ ó¸®Çϱâ À§ÇÑ »ó¼ö
enum ParseMode
{
MODE_NORMAL,
MODE_BLOCK_SCALAR,
MODE_FOLDED_SCALAR,
};
/// \struct STATE ÆÄ½ÌÀ» À§ÇÑ »óÅ ±¸Á¶Ã¼
/// \brief YAML ÆÄÀÏ Æ÷¸ËÀ» º¸¸é ¾Ë°ÚÁö¸¸, ÆÄ½ÌÀ» À§Çؼ ½ºÅÃÀÌ ÇÊ¿äÇÏ´Ù.
/// ½ºÅÿ¡´Ù °¡Àå ÃÖ±ÙÀÇ ºÎ¸ð¸¦ ÀúÀåÇØ µÎ¾î¾ß, ÇöÀç ¶óÀÎÀÇ Àε§Æ® °ª°ú
/// ºñ±³ÇØ ºÎ¸ð ÀÚ½Ä °ü°è¸¦ ÆÄ¾ÇÇÒ ¼ö ÀÖ´Ù.
struct STATE
{
cYamlTree* node;
int indent;
STATE(cYamlTree* n, int i) : node(n), indent(i) {}
};
typedef std::vector<STATE> STATE_STACK;
/// ÇöÀç Àε§Æ® °ªÀ» ±âÁØÀ¸·Î ½ºÅÿ¡¼ Á¤È®ÇÑ ºÎ¸ð¸¦ ã¾Æ, ÁÖ¾îÁø ³ëµå¸¦
/// ÀÚ½Ä ³ëµå·Î ÆíÀÔ½ÃŲ´Ù.
inline cYamlTree* AdoptChild(STATE_STACK& stateStack, int indent, cYamlTree* child)
{
while (!stateStack.empty())
{
STATE& e = stateStack.back();
if (e.indent == indent)
return e.node->AddChild(child);
else
stateStack.pop_back();
}
return NULL;
}
/// ¹®ÀÚ¿ Á¿ìÀÇ °ø¹éÀ» Á¦°ÅÇØ¼ ¹ÝȯÇÑ´Ù.
inline std::string Trim(std::string str, const std::string& whitespaces = YAML_WHITESPACES)
{
size_t begin = str.find_first_not_of(whitespaces);
size_t end = str.find_last_not_of(whitespaces);
if (begin == std::string::npos)
{
if (end == std::string::npos) return "";
else begin = 0;
}
else if (end == std::string::npos)
{
end = str.size();
}
return str.substr(begin , end - begin + 1);
}
/// \brief ÁÖ¾îÁø ¹®Àå¿¡ ÀÖ´Â ¾ËÆÄºªÀ» ¸ðµÎ ¼Ò¹®ÀÚ·Î ¹Ù²Û´Ù.
inline std::string Lower(std::string original)
{
std::transform(original.begin(), original.end(), original.begin(), tolower);
return original;
}
/// \brief ÁÖ¾îÁø ¹®ÀÚ¿ ³»¿¡ Á¸ÀçÇÏ´Â ¹®ÀÚ¿À» ´Ù¸¥ ¹®ÀÚ¿·Î ġȯÇÑ´Ù.
inline size_t Replace(std::string& text,
const std::string& findToken, const std::string& replaceToken)
{
size_t find_token_length = findToken.size();
size_t replace_token_length = replaceToken.size();
size_t replaced = 0;
size_t i = 0;
while ((i = text.find(findToken, i)) != std::string::npos)
{
text.replace(i, find_token_length, replaceToken);
i += replace_token_length;
++replaced;
}
return replaced;
}
/// \class cYamlStream
/// \brief Çü½ÄÈµÈ ÆÄÀÏ ÀÔÃâ·ÂÀ» À§ÇÑ ½ºÆ®¸² °´Ã¼. ¶óÀÎ ´ÜÀ§·Î ÆÄÀÏÀ»
/// ÀоîµéÀÌ´Â ±â´É ¿Ü¿¡ ¸¶Áö¸·À¸·Î ÀоîµéÀÎ ¹®ÀÚ¿À» ÀÌ¿ëÇØ ´ÙÀ½ ¶óÀÎÀ»
/// ¾î¶»°Ô ó¸®ÇÏ´À³Ä¸¦ ÆÇ´ÜÇÏ´Â ±â´Éµµ ´ã´çÇÑ´Ù.
class cYamlStream
{
private:
std::ifstream m_File; ///< ½ºÆ®¸² °´Ã¼
cYamlDocument* m_Document; ///< µµÅ¥¸ÕÆ® °´Ã¼
int m_Line; ///< ÇöÀç ¶óÀÎ Ä«¿îÆ®
int m_Indent; ///< ÇöÀç ¶óÀÎÀ» ÆÄ½ÌÇØ¼ ¾ò¾î³½ Àε§Æ® °ª
std::string m_Text; ///< ÇöÀç ¶óÀÎ ¹®ÀÚ¿
std::string m_Comment; ///< ÇöÀç ó¸® ÁßÀÎ ÄÚ¸àÆ®
ParseMode m_Mode; ///< Àӽà º¯¼ö
public:
/// »ý¼ºÀÚ
cYamlStream(const char* fileName, cYamlDocument* document)
: m_File(fileName, std::ios::in), m_Document(document), m_Line(0), m_Indent(0)
{
}
/// ¼Ò¸êÀÚ
~cYamlStream() {}
/// ÆÄÀÏ¿¡¼ ÇÑ ¶óÀÎÀ» ÀоîµéÀ̰í, Àε§Æ® °ªÀ» ³»ºÎ º¯¼ö¿¡´Ù ±â·ÏÇØµÐ´Ù.
inline ParseResult ParseNextLine(bool processComment)
{
++m_Line;
char buf[2048+1] = {0, };
m_File.getline(buf, 2048);
m_Text = buf;
if (m_Text.empty())
return RESULT_EMPTY; // empty line
size_t pos = m_Text.find_first_not_of(YAML_INDENT);
if (pos == std::string::npos)
{
m_Comment += "\n";
return RESULT_EMPTY; // only whitespace
}
if (processComment && m_Text[pos] == YAML_SHARP)
{
m_Comment += m_Text.substr(pos) + "\n";
return RESULT_EMPTY; // comment line
}
m_Indent = static_cast<int>(pos);
return RESULT_NORMAL;
}
/// ÇöÀç ¶óÀÎÀÇ key:value ¹®ÀÚ¿À» ÀÌ¿ëÇØ Æ®¸® °´Ã¼¸¦ »ý¼ºÇؼ ¹ÝȯÇÑ´Ù.
inline cYamlTree* CreateTree()
{
#pragma warning(push)
#pragma warning(disable:6211)
std::string text(m_Text);
cYamlTree* result = NULL;
// ':' ¹®ÀÚ¸¦ ã´Â´Ù.
size_t pos = text.find_first_of(YAML_COLON);
if (pos == std::string::npos)
throw std::string("cannot find colon character");
// ÆÄ½Ì ¼º°ø!
std::string key = Trim(text.substr(0, pos));
std::string value = Trim(text.substr(pos+1));
// Ű ¹®ÀÚ¿ÀÌ Á¤»óÀûÀÎÁö °Ë»çÇÑ´Ù.
if (key.empty())
throw std::string("key text is empty");
if (key[0] == YAML_MINUS)
{
m_Indent += static_cast<int>(key.find_first_not_of(YAML_INDENT, 1));
key = Trim(key.substr(1));
result = new cYamlTree("", "");
result->AddChild(new cYamlTree(key, value));
}
else
{
result = new cYamlTree(key, value);
}
if (!m_Comment.empty())
{
// À̶§±îÁö ¸ðÀº ÁÖ¼®À» ¼³Á¤ÇÑ´Ù. ´Ü ¸¶Áö¸·ÀÇ '\n' Çϳª´Â ¶¾´Ù.
result->SetComment(m_Comment.substr(0, m_Comment.size() - 1));
m_Comment = "";
}
if (value.size() > 1)
{
if (value[0] == YAML_AMPERSAND)
{
m_Document->AddAnchor(Trim(value.substr(1)), result);
}
else if (value[0] == YAML_ASTERISK)
{
std::string trimmed(value.substr(1));
cYamlTree* anchor = m_Document->GetAnchor(trimmed);
if (anchor == NULL)
{
delete result;
throw (std::string("no such anchor ") + trimmed);
}
result->SetAlias(anchor);
}
}
// ´ÙÀ½ ¶óÀÎÀ» ¾î¶»°Ô ó¸®ÇÒ Áö °áÁ¤ÇØ µÐ´Ù.
if (value == YAML_PIPE)
{
m_Mode = MODE_BLOCK_SCALAR;
result->SetValue("");
}
else if (value == YAML_RIGHT_BRACKET)
{
m_Mode = MODE_FOLDED_SCALAR;
result->SetValue("");
}
else
{
m_Mode = MODE_NORMAL;
}
return result;
#pragma warning(pop)
}
/// ´ÙÀ½ ¶óÀÎÀ» ¾î¶² ½ÄÀ¸·Î ó¸®ÇØ¾ß ÇÏ´ÂÁö¸¦ ¹ÝȯÇÑ´Ù.
inline ParseMode GetNextMode() const { return m_Mode; }
/// ½ºÆ®¸²ÀÇ »óŰ¡ Á¤»óÀûÀÎÁöÀÇ ¿©ºÎ¸¦ ¹ÝȯÇÑ´Ù.
inline bool IsGood() const { return m_File.good(); }
/// ÇöÀç ó¸® ÁßÀÎ ¶óÀÎÀÇ ¹øÈ£¸¦ ¹ÝȯÇÑ´Ù.
inline int GetCurrentLine() const { return m_Line; }
/// ÇöÀç ¶óÀÎÀÇ Àε§Æ® °ªÀ» ¹ÝȯÇÑ´Ù.
inline int GetIndent() const { return m_Indent; }
/// ÇöÀç ¶óÀÎ ¹®ÀÚ¿À» ¹ÝȯÇÑ´Ù.
inline const std::string& GetText() const { return m_Text; }
/// ÇöÀç ¶óÀÎÀÌ ºó ¶óÀÎ ¶Ç´Â ÄÚ¸àÆ® ¶óÀÎÀÎÁöÀÇ ¿©ºÎ¸¦ ¹ÝȯÇÑ´Ù.
inline bool IsEmptyLine() const
{
std::string trimmed(Trim(m_Text));
return trimmed.empty() || trimmed[0] == YAML_SHARP;
}
};
}
cYamlTree::PFN_ERROR_HANDLER cYamlTree::s_ParseErrorHandler = NULL;
cYamlTree::PFN_ERROR_HANDLER cYamlTree::s_AccessErrorHandler = NULL;
////////////////////////////////////////////////////////////////////////////////
/// \brief »ý¼ºÀÚ
////////////////////////////////////////////////////////////////////////////////
cYamlTree::cYamlTree()
: m_ScalarType(NORMAL_SCALAR), m_Alias(NULL), m_ChildType(CHILD_UNKNOWN),
m_MaxChildKeyLength(0)
{
}
////////////////////////////////////////////////////////////////////////////////
/// \brief »ý¼ºÀÚ
/// \param key Ű
/// \param value °ª
////////////////////////////////////////////////////////////////////////////////
cYamlTree::cYamlTree(const std::string& key, const std::string& value)
: m_Key(key), m_Value(value), m_ScalarType(NORMAL_SCALAR), m_Alias(NULL),
m_ChildType(CHILD_UNKNOWN), m_MaxChildKeyLength(0)
{
}
////////////////////////////////////////////////////////////////////////////////
/// \brief »ý¼ºÀÚ
/// \param key Ű
/// \param value °ª
////////////////////////////////////////////////////////////////////////////////
cYamlTree::cYamlTree(const std::string& key, const char* value)
: m_Key(key), m_Value(value), m_ScalarType(NORMAL_SCALAR), m_Alias(NULL),
m_ChildType(CHILD_UNKNOWN), m_MaxChildKeyLength(0)
{
}
////////////////////////////////////////////////////////////////////////////////
/// \brief »ý¼ºÀÚ
/// \param key Ű
/// \param value °ª
////////////////////////////////////////////////////////////////////////////////
cYamlTree::cYamlTree(const std::string& key, int value)
: m_Key(key), m_ScalarType(NORMAL_SCALAR), m_Alias(NULL),
m_ChildType(CHILD_UNKNOWN), m_MaxChildKeyLength(0)
{
SetValue(value);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief »ý¼ºÀÚ
/// \param key Ű
/// \param value °ª
////////////////////////////////////////////////////////////////////////////////
cYamlTree::cYamlTree(const std::string& key, float value)
: m_Key(key), m_ScalarType(NORMAL_SCALAR), m_Alias(NULL),
m_ChildType(CHILD_UNKNOWN), m_MaxChildKeyLength(0)
{
SetValue(value);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief »ý¼ºÀÚ
/// \param key Ű
/// \param value °ª
////////////////////////////////////////////////////////////////////////////////
cYamlTree::cYamlTree(const std::string& key, double value)
: m_Key(key), m_ScalarType(NORMAL_SCALAR), m_Alias(NULL),
m_ChildType(CHILD_UNKNOWN), m_MaxChildKeyLength(0)
{
SetValue(value);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief »ý¼ºÀÚ
/// \param key Ű
/// \param value °ª
////////////////////////////////////////////////////////////////////////////////
cYamlTree::cYamlTree(const std::string& key, bool value)
: m_Key(key), m_ScalarType(NORMAL_SCALAR), m_Alias(NULL),
m_ChildType(CHILD_UNKNOWN), m_MaxChildKeyLength(0)
{
SetValue(value);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ¼Ò¸êÀÚ
////////////////////////////////////////////////////////////////////////////////
cYamlTree::~cYamlTree()
{
Clear();
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ³ëµåÀÇ °ªÀ» std::string ¹ÝȯÇÑ´Ù.
/// \return const std::string& °ª ¹®ÀÚ¿
////////////////////////////////////////////////////////////////////////////////
const std::string& cYamlTree::GetValue() const
{
return m_Alias == NULL ? m_Value : m_Alias->GetValue();
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ³ëµåÀÇ °ªÀ» char* ÇüÅ·Π¹ÝȯÇÑ´Ù.
/// \return const char* °ª ¹®ÀÚ¿
////////////////////////////////////////////////////////////////////////////////
const char* cYamlTree::GetValueAsString() const
{
return m_Alias == NULL ? m_Value.c_str() : m_Alias->GetValueAsString();
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ³ëµåÀÇ °ªÀ» int ÇüÅ·Πº¯È¯Çؼ ¹ÝȯÇÑ´Ù.
/// \return int º¯È¯ÇÑ °ª
////////////////////////////////////////////////////////////////////////////////
int cYamlTree::GetValueAsInt() const
{
return m_Alias == NULL ? atoi(GetValueAsString()) : m_Alias->GetValueAsInt();
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ³ëµåÀÇ °ªÀ» float ÇüÅ·Πº¯È¯Çؼ ¹ÝȯÇÑ´Ù.
/// \return float º¯È¯ÇÑ °ª
////////////////////////////////////////////////////////////////////////////////
float cYamlTree::GetValueAsFloat() const
{
return m_Alias == NULL ?
static_cast<float>(atof(GetValueAsString())) : m_Alias->GetValueAsFloat();
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ³ëµåÀÇ °ªÀ» double ÇüÅ·Πº¯È¯Çؼ ¹ÝȯÇÑ´Ù.
/// \return double º¯È¯ÇÑ °ª
////////////////////////////////////////////////////////////////////////////////
double cYamlTree::GetValueAsDouble() const
{
return m_Alias == NULL ? atof(GetValueAsString()) : m_Alias->GetValueAsDouble();
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ³ëµåÀÇ °ªÀ» bool ÇüÅ·Πº¯È¯Çؼ ¹ÝȯÇÑ´Ù.
/// \return bool º¯È¯ÇÑ °ª. ³ëµåÀÇ °ªÀÌ ´ë¼Ò¹®ÀÚ ±¸º° ¾øÀÌ "true"ÀÏ °æ¿ì¿¡¸¸
/// true°¡ µÇ°í, ±× ¿Ü¿¡´Â ¸ðµÎ false·Î Ãë±ÞÇÑ´Ù.
////////////////////////////////////////////////////////////////////////////////
bool cYamlTree::GetValueAsBool() const
{
#if _MSC_VER >= 1400
return m_Alias == NULL ?
_stricmp(m_Value.c_str(), "true") == 0 : m_Alias->GetValueAsBool();
#else
return m_Alias == NULL ?
stricmp(m_Value.c_str(), "true") == 0 : m_Alias->GetValueAsBool();
#endif
}
////////////////////////////////////////////////////////////////////////////////
/// \brief °ª ¹®ÀÚ¿À» ¼³Á¤ÇÑ´Ù.
/// \param value ¼³Á¤ÇÒ °ª
////////////////////////////////////////////////////////////////////////////////
void cYamlTree::SetValue(const std::string& value)
{
if (m_Alias == NULL)
m_Value = value;
else
m_Alias->SetValue(value);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief °ª ¹®ÀÚ¿À» ¼³Á¤ÇÑ´Ù.
/// \param value ¼³Á¤ÇÒ °ª
////////////////////////////////////////////////////////////////////////////////
void cYamlTree::SetValue(const char* value)
{
if (m_Alias == NULL)
m_Value = value;
else
m_Alias->SetValue(value);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief int ÇüÅ·Π°ªÀ» ¼³Á¤ÇÑ´Ù.
/// \param value ¼³Á¤ÇÒ °ª
////////////////////////////////////////////////////////////////////////////////
void cYamlTree::SetValue(int value)
{
char buf[256] = {0,};
#if _MSC_VER >= 1400
_snprintf_s(buf, sizeof(buf)-1, _TRUNCATE, "%d", value);
#else
sprintf(buf, "%d", value);
#endif
buf[sizeof(buf)-1] = 0;
SetValue(buf);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief float ÇüÅ·Π°ªÀ» ¼³Á¤ÇÑ´Ù.
/// \param value ¼³Á¤ÇÒ °ª
////////////////////////////////////////////////////////////////////////////////
void cYamlTree::SetValue(float value)
{
char buf[256] = {0,};
#if _MSC_VER >= 1400
_snprintf_s(buf, sizeof(buf)-1, _TRUNCATE, "%f", value);
#else
sprintf(buf, "%f", value);
#endif
buf[sizeof(buf)-1] = 0;
SetValue(buf);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief double ÇüÅ·Π°ªÀ» ¼³Á¤ÇÑ´Ù.
/// \param value ¼³Á¤ÇÒ °ª
////////////////////////////////////////////////////////////////////////////////
void cYamlTree::SetValue(double value)
{
char buf[256] = {0,};
#if _MSC_VER >= 1400
_snprintf_s(buf, sizeof(buf)-1, _TRUNCATE, "%f", value);
#else
sprintf(buf, "%f", value);
#endif
buf[sizeof(buf)-1] = 0;
SetValue(buf);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief bool ÇüÅ·Π°ªÀ» ¼³Á¤ÇÑ´Ù.
/// \param value ¼³Á¤ÇÒ °ª
////////////////////////////////////////////////////////////////////////////////
void cYamlTree::SetValue(bool value)
{
SetValue(value ? "true" : "false");
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÁÖ¼® ¹®ÀÚ¿À» ¹ÝȯÇÑ´Ù.
/// \return const std::string&
////////////////////////////////////////////////////////////////////////////////
const std::string& cYamlTree::GetComment() const
{
return m_Alias == NULL ? m_Comment : m_Alias->GetComment();
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÁÖ¼® ¹®ÀÚ¿À» ¼³Á¤ÇÑ´Ù.
/// \param comment ÁÖ¼® ¹®ÀÚ¿
////////////////////////////////////////////////////////////////////////////////
void cYamlTree::SetComment(const std::string& comment)
{
if (m_Alias == NULL)
m_Comment = comment;
else
m_Alias->SetComment(comment);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief °ªÀÇ Á¾·ù¸¦ ¹ÝȯÇÑ´Ù.
/// \return cYamlTree::ScalarType °ªÀÇ Á¾·ù
////////////////////////////////////////////////////////////////////////////////
cYamlTree::ScalarType cYamlTree::GetScalarType() const
{
return m_Alias == NULL ? m_ScalarType : m_Alias->GetScalarType();
}
////////////////////////////////////////////////////////////////////////////////
/// \brief °ªÀÇ Á¾·ù¸¦ ¼³Á¤ÇÑ´Ù.
/// \param type °ªÀÇ Á¾·ù
////////////////////////////////////////////////////////////////////////////////
void cYamlTree::SetScalarType(cYamlTree::ScalarType type)
{
if (m_Alias == NULL)
m_ScalarType = type;
else
m_Alias->SetScalarType(type);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ½ºÄ®¶ó °ªÀ» Ãß°¡ÇÑ´Ù.
/// \param value ½ºÄ®¶ó °ª
////////////////////////////////////////////////////////////////////////////////
void cYamlTree::AddScalar(const std::string& value)
{
if (m_Alias == NULL)
m_Scalars.push_back(value);
else
m_Alias->AddScalar(value);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ½ºÄ®¶ó °ªÀÇ Ä÷º¼ÇÀ» ¹ÝȯÇÑ´Ù.
/// \return const cYamlTree::SCALARS& ½ºÄ®¶ó °ªÀÇ Ä÷º¼Ç
////////////////////////////////////////////////////////////////////////////////
const cYamlTree::SCALARS& cYamlTree::GetScalars() const
{
return m_Alias == NULL ? m_Scalars : m_Alias->GetScalars();
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ¾ÞÄ¿ ¾Ë¸®¾Æ½º¸¦ ¹ÝȯÇÑ´Ù.
/// \return cYamlTree* ¾Ë¸®¾Æ½º
////////////////////////////////////////////////////////////////////////////////
cYamlTree* cYamlTree::GetAlias() const
{
return m_Alias;
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ¾ÞÄ¿ ¾Ë¸®¾Æ½º¸¦ ¼³Á¤ÇÑ´Ù.
/// \param alias ¾Ë¸®¾Æ½º
////////////////////////////////////////////////////////////////////////////////
void cYamlTree::SetAlias(cYamlTree* alias)
{
if (alias != this) m_Alias = alias;
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÀÚ½Ä ³ëµå¸¦ Ãß°¡ÇÑ´Ù. Ãß°¡ÇÑ ÀÚ½Ä ³ëµå´Â ³»ºÎ¿¡¼ delete·Î
/// »èÁ¦ÇϹǷΠ¹Ýµå½Ã new¸¦ ÅëÇØ Èü¿¡´Ù »ý¼ºÇØ¾ß ÇÑ´Ù.
/// \param child Ãß°¡ÇÒ ÀÚ½Ä ³ëµå
/// \return cYamlTree* Àμö·Î ÁÖ¾îÁø child ¸¦ ¹ÝȯÇÑ´Ù.
////////////////////////////////////////////////////////////////////////////////
cYamlTree* cYamlTree::AddChild(cYamlTree* child)
{
if (m_Alias)
{
throw std::string("cannot add child to aliased node");
}
// ÀÚ½Ä ³ëµå°¡ ÀÖ´Â °æ¿ì ½ºÄ®¶ó °ªÀ» °¡Áú ¼ö ¾ø´Ù.
if (!m_Value.empty() &&
m_Value[0] != YAML_AMPERSAND &&
m_Value[0] != YAML_ASTERISK)
{
throw std::string("cannot add child to scalar node");
}
// ÀÚ½Ä ³ëµåÀÇ key ¹®ÀÚ¿ÀÌ ºó ¹®ÀÚ¿À̶ó¸é,
// ÀÌ´Â ¹è¿À» ÀÌ¿ëÇØ¾ß µÈ´Ù´Â ¸»ÀÌ´Ù.
if (child->GetKey().empty())
{
// ÃÖÃÊÀÇ ÀÚ½Ä ³ëµå¶ó¸é ChildTypeÀÌ UNKNOWNÀÏ °ÍÀÌ´Ù.
if (m_ChildType == CHILD_UNKNOWN)
m_ChildType = CHILD_SEQNENTIAL;
// ÃÖÃÊ ÀÌÈĺÎÅÍ´Â °°Àº ŸÀÔÀÇ ÀÚ½Ä ³ëµå¸¸ÀÌ µé¾î¿Í¾ßÇÑ´Ù.
if (m_ChildType != CHILD_SEQNENTIAL)
throw std::string("cannot add sequencial node");
char buf[1024] = {0, };
#if _MSC_VER >= 1400
_snprintf_s(buf, sizeof(buf)-1, _TRUNCATE, "%05d", m_SequentialChilds.size());
#else
sprintf(buf, "%05d", m_SequentialChilds.size());
#endif
buf[sizeof(buf)-1] = 0;
m_SequentialChilds.push_back(child);
m_MappedChilds.insert(MAPPING::value_type(std::string(buf), child));
return child;
}
// ÀÚ½Ä ³ëµåÀÇ key ¹®ÀÚ¿ÀÌ ºó ¹®ÀÚ¿ÀÌ ¾Æ´Ï¶ó¸é,
// ¸ÊÀ» ÀÌ¿ëÇØ¼ ÀÚ½Ä ³ëµå¸¦ °ü¸®ÇØ¾ß ÇÑ´Ù.
else
{
// ÃÖÃÊÀÇ ÀÚ½Ä ³ëµå¶ó¸é ChildTypeÀÌ UNKNOWNÀÏ °ÍÀÌ´Ù.
if (m_ChildType == CHILD_UNKNOWN)
m_ChildType = CHILD_MAPPED;
// ÃÖÃÊ ÀÌÈĺÎÅÍ´Â °°Àº ŸÀÔÀÇ ÀÚ½Ä ³ëµå¸¸ÀÌ µé¾î¿Í¾ßÇÑ´Ù.
if (m_ChildType != CHILD_MAPPED)
throw std::string("cannot add mapped node");
MAPPING::const_iterator itr(m_MappedChilds.find(Lower(child->GetKey())));
if (itr == m_MappedChilds.end())
{
#ifdef NOMINMAX
m_MaxChildKeyLength = std::max(m_MaxChildKeyLength, child->GetKey().size());
#else
m_MaxChildKeyLength = __max(m_MaxChildKeyLength, child->GetKey().size());
#endif
m_MappedChilds.insert(MAPPING::value_type(Lower(child->GetKey()), child));
m_SequentialChilds.push_back(child);
return child;
}
else
{
char buf[1024] = {0, };
#if _MSC_VER >= 1400
_snprintf_s(buf, sizeof(buf)-1, _TRUNCATE,
"cannot add duplicated mapping - %s", child->GetKey().c_str());
#else
sprintf(buf,
"cannot add duplicated mapping - %s", child->GetKey().c_str());
#endif
buf[sizeof(buf)-1] = 0;
throw std::string(buf);
}
}
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÇØ´çÇÏ´Â ÀÚ½Ä ³ëµå¸¦ °¡Áö°í ÀÖ´ÂÁöÀÇ ¿©ºÎ¸¦ ¹ÝȯÇÑ´Ù.
/// \param key Ű
/// \return cYamlTree* ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå°¡ ÀÖ´Ù¸é true¸¦ ¹ÝȯÇϰí,
/// ¾ø´Ù¸é false¸¦ ¹ÝȯÇÑ´Ù.
////////////////////////////////////////////////////////////////////////////////
bool cYamlTree::HasChild(const std::string& key) const
{
if (m_Alias) return m_Alias->HasChild(key);
if (m_ChildType == CHILD_MAPPED)
{
if (m_MappedChilds.find(Lower(key)) != m_MappedChilds.end()) return true;
}
else if (m_ChildType == CHILD_SEQNENTIAL)
{
size_t size = m_SequentialChilds.size();
for (size_t i=0; i<size; ++i)
{
const cYamlTree* const child = m_SequentialChilds[i];
if (child->GetKey() == key) return true;
}
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÇØ´çÇÏ´Â À妽ºÀÇ ÀÚ½Ä ³ëµå¸¦ ¹ÝȯÇÑ´Ù.
/// \param i À妽º
/// \param strict ÇØ´çÇÏ´Â ÀÚ½Ä ³ëµå°¡ Á¸ÀçÇÏÁö ¾ÊÀ» °æ¿ì, ¾î¼Æ®¸¦ ¹ß»ý½Ãų
/// °ÍÀΰ¡ÀÇ ¿©ºÎ
/// \return cYamlTree* ÀÚ½Ä ³ëµå
////////////////////////////////////////////////////////////////////////////////
cYamlTree* cYamlTree::GetChild(size_t i, bool strict) const
{
if (m_Alias)
return m_Alias->GetChild(i, strict);
if (i < m_SequentialChilds.size())
return m_SequentialChilds[i];
if (strict)
{
char buf[1024] = {0, };
#if _MSC_VER >= 1400
_snprintf_s(buf, sizeof(buf)-1, _TRUNCATE,
"out of range in node %s with %d", m_Key.c_str(), i);
#else
sprintf(buf,
"out of range in node %s with %d", m_Key.c_str(), i);
#endif
buf[sizeof(buf)-1] = 0;
throw std::string(buf);
}
return NULL;
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÇØ´çÇÏ´Â À妽ºÀÇ ÀÚ½Ä ³ëµå¸¦ ¹ÝȯÇÑ´Ù.
/// \param i À妽º
/// \return const cYamlTree& ÇØ´çÇÏ´Â À妽ºÀÇ ÀÚ½Ä ³ëµå. ¹üÀ§¸¦ ³Ñ¾î°£ °æ¿ì
/// ¾îµð¸¦ °¡¸£Å°°Ô µÉÁö´Â ¸ð¸¥´Ù.
////////////////////////////////////////////////////////////////////////////////
cYamlTree& cYamlTree::operator[](size_t i)
{
return *GetChild(i, true);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÇØ´çÇÏ´Â À妽ºÀÇ ÀÚ½Ä ³ëµå¸¦ ¹ÝȯÇÑ´Ù.
/// \param i À妽º
/// \return const cYamlTree& ÇØ´çÇÏ´Â À妽ºÀÇ ÀÚ½Ä ³ëµå. ¹üÀ§¸¦ ³Ñ¾î°£ °æ¿ì
/// ¾îµð¸¦ °¡¸£Å°°Ô µÉÁö´Â ¸ð¸¥´Ù.
////////////////////////////////////////////////////////////////////////////////
const cYamlTree& cYamlTree::operator[](size_t i) const
{
return *GetChild(i, true);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÀÚ½Ä ³ëµåÀÇ °¹¼ö¸¦ ¹ÝȯÇÑ´Ù.
/// \return size_t ÀÚ½Ä ³ëµåÀÇ °¹¼ö
////////////////////////////////////////////////////////////////////////////////
size_t cYamlTree::GetChildCount() const
{
if (m_Alias) return m_Alias->GetChildCount();
if (m_ChildType == CHILD_MAPPED) return m_MappedChilds.size();
if (m_ChildType == CHILD_SEQNENTIAL) return m_SequentialChilds.size();
return 0;
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå¸¦ ¹ÝȯÇÑ´Ù.
/// \param key Ű
/// \param strict ÇØ´çÇÏ´Â ÀÚ½Ä ³ëµå°¡ Á¸ÀçÇÏÁö ¾ÊÀ» °æ¿ì, ¾î¼Æ®¸¦ ¹ß»ý½Ãų
/// °ÍÀΰ¡ÀÇ ¿©ºÎ
/// \return cYamlTree* ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå°¡ ÀÖ´Ù¸é ±× ³ëµåÀÇ Æ÷ÀÎÅ͸¦
/// ¹ÝȯÇϰí, ¾ø´Ù¸é NULLÀ» ¹ÝȯÇÑ´Ù.
////////////////////////////////////////////////////////////////////////////////
cYamlTree* cYamlTree::GetChild(const std::string& key, bool strict) const
{
if (m_Alias) return m_Alias->GetChild(key, strict);
if (m_ChildType == CHILD_MAPPED)
{
MAPPING::const_iterator itr(m_MappedChilds.find(Lower(key)));
if (itr != m_MappedChilds.end()) return itr->second;
if (strict)
{
char buf[1024] = {0, };
#if _MSC_VER >= 1400
_snprintf_s(buf, sizeof(buf)-1, _TRUNCATE,
"cannot find specified child node %s at %s",
key.c_str(), m_Key.c_str());
#else
sprintf(buf,
"cannot find specified child node %s at %s",
key.c_str(), m_Key.c_str());
#endif
buf[sizeof(buf)-1] = 0;
if (s_AccessErrorHandler)
s_AccessErrorHandler(buf);
else
throw std::string(buf);
}
return NULL;
}
else if (m_ChildType == CHILD_SEQNENTIAL)
{
size_t size = m_SequentialChilds.size();
for (size_t i=0; i<size; ++i)
{
cYamlTree* child = m_SequentialChilds[i];
if (child->GetKey() == key) return child;
}
if (strict)
{
char buf[1024] = {0, };
#if _MSC_VER >= 1400
_snprintf_s(buf, sizeof(buf)-1, _TRUNCATE,
"cannot find specified child node %s at %s",
key.c_str(), m_Key.c_str());
#else
sprintf(buf,
"cannot find specified child node %s at %s",
key.c_str(), m_Key.c_str());
#endif
buf[sizeof(buf)-1] = 0;
if (s_AccessErrorHandler)
s_AccessErrorHandler(buf);
else
throw std::string(buf);
}
return NULL;
}
if (strict)
{
char buf[1024] = {0, };
#if _MSC_VER >= 1400
_snprintf_s(buf, sizeof(buf)-1, _TRUNCATE,
"cannot find specified child node %s at %s",
key.c_str(), m_Key.c_str());
#else
sprintf(buf,
"cannot find specified child node %s at %s",
key.c_str(), m_Key.c_str());
#endif
buf[sizeof(buf)-1] = 0;
if (s_AccessErrorHandler)
s_AccessErrorHandler(buf);
else
throw std::string(buf);
}
return NULL;
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå Áß¿¡ ù¹øÂ° °ÍÀ» ¹ÝȯÇÑ´Ù.
/// \param key Ű
/// \return const cYamlTree& ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå. ÇØ´çÇÏ´Â ÀÚ½Ä ³ëµå°¡
/// ¾øÀ» °æ¿ì¿¡´Â ¾î¶»°Ô µÉ Áö ¸ð¸¥´Ù.
////////////////////////////////////////////////////////////////////////////////
cYamlTree& cYamlTree::operator[](const std::string& key)
{
return *GetChild(key, true);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå Áß¿¡ ù¹øÂ° °ÍÀ» ¹ÝȯÇÑ´Ù.
/// \param key Ű
/// \return const cYamlTree& ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå. ÇØ´çÇÏ´Â ÀÚ½Ä ³ëµå°¡
/// ¾øÀ» °æ¿ì¿¡´Â ¾î¶»°Ô µÉ Áö ¸ð¸¥´Ù.
////////////////////////////////////////////////////////////////////////////////
const cYamlTree& cYamlTree::operator[](const std::string& key) const
{
return *GetChild(key, true);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå¸¦ ã¾Æ, ±× ³ëµåÀÇ ÅØ½ºÆ® °ªÀ»
/// const char* ÇüÅ·Π¹ÝȯÇÑ´Ù.
/// \param key Ű
/// \return const char* ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå°¡ ÀÖ´Ù¸é ±× ³ëµåÀÇ °ªÀ»
/// ¹ÝȯÇϰí, ¾ø´Ù¸é ºó ¹®ÀÚ¿À» ¹ÝȯÇÑ´Ù.
/// \note ÇØ´çÇÏ´Â ÀÚ½Ä ³ëµå°¡ ¾ø´Â °æ¿ì, µð¹ö±× ¹öÀü¿¡¼´Â ¾î¼Æ®¸¦ ¹ß»ý½ÃŲ´Ù.
////////////////////////////////////////////////////////////////////////////////
const char* cYamlTree::AttrAsString(const std::string& key) const
{
cYamlTree* child = GetChild(key, true);
return child ? child->GetValueAsString() : "";
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå¸¦ ã¾Æ, ±× ³ëµåÀÇ ÅØ½ºÆ® °ªÀ»
/// int ÇüÅ·Π¹ÝȯÇÑ´Ù.
/// \param key Ű
/// \return int ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå°¡ ÀÖ´Ù¸é ±× ³ëµåÀÇ °ªÀ»
/// ¹ÝȯÇϰí, ¾ø´Ù¸é -1À» ¹ÝȯÇÑ´Ù.
/// \note ÇØ´çÇÏ´Â ÀÚ½Ä ³ëµå°¡ ¾ø´Â °æ¿ì, µð¹ö±× ¹öÀü¿¡¼´Â ¾î¼Æ®¸¦ ¹ß»ý½ÃŲ´Ù.
////////////////////////////////////////////////////////////////////////////////
int cYamlTree::AttrAsInt(const std::string& key) const
{
cYamlTree* child = GetChild(key, true);
return child ? child->GetValueAsInt() : -1;
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå¸¦ ã¾Æ, ±× ³ëµåÀÇ ÅØ½ºÆ® °ªÀ»
/// float ÇüÅ·Π¹ÝȯÇÑ´Ù.
/// \param key Ű
/// \return float ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå°¡ ÀÖ´Ù¸é ±× ³ëµåÀÇ °ªÀ»
/// ¹ÝȯÇϰí, ¾ø´Ù¸é -1.0f¸¦ ¹ÝȯÇÑ´Ù.
/// \note ÇØ´çÇÏ´Â ÀÚ½Ä ³ëµå°¡ ¾ø´Â °æ¿ì, µð¹ö±× ¹öÀü¿¡¼´Â ¾î¼Æ®¸¦ ¹ß»ý½ÃŲ´Ù.
////////////////////////////////////////////////////////////////////////////////
float cYamlTree::AttrAsFloat(const std::string& key) const
{
cYamlTree* child = GetChild(key, true);
return child ? child->GetValueAsFloat() : -1.0f;
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå¸¦ ã¾Æ, ±× ³ëµåÀÇ ÅØ½ºÆ® °ªÀ» double
/// ÇüÅ·Π¹ÝȯÇÑ´Ù.
/// \param key Ű
/// \return double ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå°¡ ÀÖ´Ù¸é ±× ³ëµåÀÇ °ªÀ»
/// ¹ÝȯÇϰí, ¾ø´Ù¸é -1.0À» ¹ÝȯÇÑ´Ù.
/// \note ÇØ´çÇÏ´Â ÀÚ½Ä ³ëµå°¡ ¾ø´Â °æ¿ì, µð¹ö±× ¹öÀü¿¡¼´Â ¾î¼Æ®¸¦ ¹ß»ý½ÃŲ´Ù.
////////////////////////////////////////////////////////////////////////////////
double cYamlTree::AttrAsDouble(const std::string& key) const
{
cYamlTree* child = GetChild(key, true);
return child ? child->GetValueAsDouble() : -1.0;
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå¸¦ ã¾Æ, ±× ³ëµåÀÇ ÅØ½ºÆ® °ªÀ»
/// bool ÇüÅ·Π¹ÝȯÇÑ´Ù.
/// \param key Ű
/// \return bool ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå°¡ ÀÖ´Ù¸é ±× ³ëµåÀÇ °ªÀ»
/// ¹ÝȯÇϰí, ¾ø´Ù¸é false¸¦ ¹ÝȯÇÑ´Ù.
/// \note ÇØ´çÇÏ´Â ÀÚ½Ä ³ëµå°¡ ¾ø´Â °æ¿ì, µð¹ö±× ¹öÀü¿¡¼´Â ¾î¼Æ®¸¦ ¹ß»ý½ÃŲ´Ù.
////////////////////////////////////////////////////////////////////////////////
bool cYamlTree::AttrAsBool(const std::string& key) const
{
cYamlTree* child = GetChild(key, true);
return child ? child->GetValueAsBool() : false;
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå¸¦ ã¾Æ, ±× ³ëµåÀÇ ÅØ½ºÆ® °ªÀ»
/// const char* ÇüÅ·Π¹ÝȯÇÑ´Ù.
/// \param key Ű
/// \param nullValue ÇØ´çÇÏ´Â ÀÚ½Ä ³ëµå°¡ Á¸ÀçÇÏÁö ¾ÊÀ» °æ¿ì¿¡ ¹ÝȯÇÒ °ª
/// \return const char* ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå°¡ ÀÖ´Ù¸é ±× ³ëµåÀÇ °ªÀ»
/// ¹ÝȯÇϰí, ¾ø´Ù¸é ÁÖ¾îÁø nullValue¸¦ ¹ÝȯÇÑ´Ù.
////////////////////////////////////////////////////////////////////////////////
const char* cYamlTree::AttrAsStringSafe(const std::string& key, const char* nullValue) const
{
cYamlTree* child = GetChild(key, false);
return child ? child->GetValueAsString() : nullValue;
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå¸¦ ã¾Æ, ±× ³ëµåÀÇ ÅØ½ºÆ® °ªÀ»
/// int ÇüÅ·Π¹ÝȯÇÑ´Ù.
/// \param key Ű
/// \param nullValue ÇØ´çÇÏ´Â ÀÚ½Ä ³ëµå°¡ Á¸ÀçÇÏÁö ¾ÊÀ» °æ¿ì¿¡ ¹ÝȯÇÒ °ª
/// \return int ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå°¡ ÀÖ´Ù¸é ±× ³ëµåÀÇ °ªÀ»
/// ¹ÝȯÇϰí, ¾ø´Ù¸é ÁÖ¾îÁø nullValue¸¦ ¹ÝȯÇÑ´Ù.
////////////////////////////////////////////////////////////////////////////////
int cYamlTree::AttrAsIntSafe(const std::string& key, int nullValue) const
{
cYamlTree* child = GetChild(key, false);
return child ? child->GetValueAsInt() : nullValue;
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå¸¦ ã¾Æ, ±× ³ëµåÀÇ ÅØ½ºÆ® °ªÀ»
/// float ÇüÅ·Π¹ÝȯÇÑ´Ù.
/// \param key Ű
/// \param nullValue ÇØ´çÇÏ´Â ÀÚ½Ä ³ëµå°¡ Á¸ÀçÇÏÁö ¾ÊÀ» °æ¿ì¿¡ ¹ÝȯÇÒ °ª
/// \return float ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå°¡ ÀÖ´Ù¸é ±× ³ëµåÀÇ °ªÀ»
/// ¹ÝȯÇϰí, ¾ø´Ù¸é ÁÖ¾îÁø nullValue¸¦ ¹ÝȯÇÑ´Ù.
////////////////////////////////////////////////////////////////////////////////
float cYamlTree::AttrAsFloatSafe(const std::string& key, float nullValue) const
{
cYamlTree* child = GetChild(key, false);
return child ? child->GetValueAsFloat() : nullValue;
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå¸¦ ã¾Æ, ±× ³ëµåÀÇ ÅØ½ºÆ® °ªÀ»
/// double ÇüÅ·Π¹ÝȯÇÑ´Ù.
/// \param key Ű
/// \param nullValue ÇØ´çÇÏ´Â ÀÚ½Ä ³ëµå°¡ Á¸ÀçÇÏÁö ¾ÊÀ» °æ¿ì¿¡ ¹ÝȯÇÒ °ª
/// \return double ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå°¡ ÀÖ´Ù¸é ±× ³ëµåÀÇ °ªÀ»
/// ¹ÝȯÇϰí, ¾ø´Ù¸é ÁÖ¾îÁø nullValue¸¦ ¹ÝȯÇÑ´Ù.
////////////////////////////////////////////////////////////////////////////////
double cYamlTree::AttrAsDoubleSafe(const std::string& key, double nullValue) const
{
cYamlTree* child = GetChild(key, false);
return child ? child->GetValueAsDouble() : nullValue;
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå¸¦ ã¾Æ, ±× ³ëµåÀÇ ÅØ½ºÆ® °ªÀ»
/// bool ÇüÅ·Π¹ÝȯÇÑ´Ù.
/// \param key Ű
/// \param nullValue ÇØ´çÇÏ´Â ÀÚ½Ä ³ëµå°¡ Á¸ÀçÇÏÁö ¾ÊÀ» °æ¿ì¿¡ ¹ÝȯÇÒ °ª
/// \return bool ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå°¡ ÀÖ´Ù¸é ±× ³ëµåÀÇ °ªÀ»
/// ¹ÝȯÇϰí, ¾ø´Ù¸é ÁÖ¾îÁø nullValue¸¦ ¹ÝȯÇÑ´Ù.
////////////////////////////////////////////////////////////////////////////////
bool cYamlTree::AttrAsBoolSafe(const std::string& key, bool nullValue) const
{
cYamlTree* child = GetChild(key, false);
return child ? child->GetValueAsBool() : nullValue;
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÀÚ½Ä ³ëµå¸¦ Ãß°¡ÇÑ´Ù.
/// \param key Ű
/// \param value °ª
/// \return cYamlTree* Ãß°¡ÇÑ ÀÚ½Ä ³ëµåÀÇ Æ÷ÀÎÅÍ
////////////////////////////////////////////////////////////////////////////////
cYamlTree* cYamlTree::AddAttr(const std::string& key, const std::string& value)
{
return AddChild(new cYamlTree(key, value));
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÀÚ½Ä ³ëµå¸¦ Ãß°¡ÇÑ´Ù.
/// \param key Ű
/// \param value °ª
/// \return cYamlTree* Ãß°¡ÇÑ ÀÚ½Ä ³ëµåÀÇ Æ÷ÀÎÅÍ
////////////////////////////////////////////////////////////////////////////////
cYamlTree* cYamlTree::AddAttr(const std::string& key, const char* value)
{
return AddChild(new cYamlTree(key, value));
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÀÚ½Ä ³ëµå¸¦ Ãß°¡ÇÑ´Ù.
/// \param key Ű
/// \param value °ª
/// \return cYamlTree* Ãß°¡ÇÑ ÀÚ½Ä ³ëµåÀÇ Æ÷ÀÎÅÍ
////////////////////////////////////////////////////////////////////////////////
cYamlTree* cYamlTree::AddAttr(const std::string& key, int value)
{
return AddChild(new cYamlTree(key, value));
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÀÚ½Ä ³ëµå¸¦ Ãß°¡ÇÑ´Ù.
/// \param key Ű
/// \param value °ª
/// \return cYamlTree* Ãß°¡ÇÑ ÀÚ½Ä ³ëµåÀÇ Æ÷ÀÎÅÍ
////////////////////////////////////////////////////////////////////////////////
cYamlTree* cYamlTree::AddAttr(const std::string& key, float value)
{
return AddChild(new cYamlTree(key, value));
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÀÚ½Ä ³ëµå¸¦ Ãß°¡ÇÑ´Ù.
/// \param key Ű
/// \param value °ª
/// \return cYamlTree* Ãß°¡ÇÑ ÀÚ½Ä ³ëµåÀÇ Æ÷ÀÎÅÍ
////////////////////////////////////////////////////////////////////////////////
cYamlTree* cYamlTree::AddAttr(const std::string& key, double value)
{
return AddChild(new cYamlTree(key, value));
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÀÚ½Ä ³ëµå¸¦ Ãß°¡ÇÑ´Ù.
/// \param key Ű
/// \param value °ª
/// \return cYamlTree* Ãß°¡ÇÑ ÀÚ½Ä ³ëµåÀÇ Æ÷ÀÎÅÍ
////////////////////////////////////////////////////////////////////////////////
cYamlTree* cYamlTree::AddAttr(const std::string& key, bool value)
{
return AddChild(new cYamlTree(key, value));
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÀڽŠ¹× ¸ðµç ÀÚ½Ä ³ëµåµéÀ» ÃʱâÈÇÑ´Ù.
////////////////////////////////////////////////////////////////////////////////
void cYamlTree::Clear()
{
if (m_SequentialChilds.size() != m_MappedChilds.size())
{
char buf[1024] = {0, };
#if _MSC_VER >= 1400
_snprintf_s(buf, sizeof(buf)-1, _TRUNCATE,
"child count mismatch at node %s", m_Key.c_str());
#else
sprintf(buf,
"child count mismatch at node %s", m_Key.c_str());
#endif
buf[sizeof(buf)-1] = 0;
if (s_AccessErrorHandler)
s_AccessErrorHandler(buf);
else
throw std::string(buf);
}
m_Key = "";
m_Value = "";
m_Comment = "";
m_ScalarType = NORMAL_SCALAR;
m_Scalars.clear();
m_Alias = NULL;
m_ChildType = CHILD_UNKNOWN;
m_MaxChildKeyLength = 0;
size_t size = m_SequentialChilds.size();
for (size_t i=0; i<size; ++i)
delete m_SequentialChilds[i];
m_SequentialChilds.clear();
m_MappedChilds.clear();
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ³»ºÎ µ¥ÀÌÅ͸¦ ¹®ÀÚ¿ ÇüÅ·Π¹ÝȯÇÑ´Ù.
/// \param beautify Ãâ·Â ÆÄÀÏÀÇ Àε§Æ®¸¦ ¿¹»Ú°Ô Á¤·ÄÇÒ °ÍÀΰ¡ÀÇ ¿©ºÎ
/// \param includeSelf ÀÚ±â Àڽŵµ Ãâ·Â¿¡ Æ÷ÇÔ½Ãų °ÍÀΰ¡ÀÇ ¿©ºÎ
/// \return std::string ¹®ÀÚ¿ ÇüÅ·Πº¯È¯ÇÑ µ¥ÀÌÅÍ
////////////////////////////////////////////////////////////////////////////////
std::string cYamlTree::ToString(bool beautify, bool includeSelf) const
{
std::stringstream msg;
// ÇöÀç ³ëµåÀÇ ±íÀÌ¿¡ ¸ÂÃç ÁÖ¼®À» ±â·ÏÇØÁØ´Ù. À¯ÀÇÇÒ Á¡Àº °ø¹é ¹®Àڷθ¸
// ÀÌ·ç¾îÁø ÁÖ¼®Àº ¾Õ¿¡´Ù '#' ¹®ÀÚ¸¦ Ãâ·ÂÇÏÁö ¾Ê´Â´Ù´Â Á¡ÀÌ´Ù. ±×³É ºó ÁÙÀ»
// Ãâ·ÂÇϱâ À§ÇؼÀÌ´Ù.
if (!m_Comment.empty())
msg << m_Comment << std::endl;
if (includeSelf)
msg << m_Key << ":" << m_Value << std::endl;
size_t size = m_SequentialChilds.size();
bool mapped = m_ChildType == CHILD_MAPPED;
for (size_t i=0; i<size; ++i)
{
const cYamlTree* const child = m_SequentialChilds[i];
msg << child->ToString(0, mapped, "", beautify, m_MaxChildKeyLength);
}
return msg.str();
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ³»ºÎ µ¥ÀÌÅ͸¦ ¹®ÀÚ¿ ÇüÅ·Π¹ÝȯÇÑ´Ù.
/// \param indent µé¿©¾²±âÇÒ Ä
/// \param mapped ºÎ¸ð ³ëµåÀÇ child type
/// \param header Ű ¹®ÀÚ¿ Ãâ·Â½Ã ¾Õ¿¡´Ù ºÙÀÏ Çì´õ
/// \param beautify Ãâ·Â ÆÄÀÏÀÇ Àε§Æ®¸¦ ¿¹»Ú°Ô Á¤·ÄÇÒ °ÍÀΰ¡ÀÇ ¿©ºÎ
/// \param maxKeyLength Àε§Æ®¸¦ ¿¹»Ú°Ô Çϴµ¥ »ç¿ëÇÒ °ª
/// \return std::string ¹®ÀÚ¿ ÇüÅ·Πº¯È¯ÇÑ µ¥ÀÌÅÍ
////////////////////////////////////////////////////////////////////////////////
std::string cYamlTree::ToString(size_t indent, bool mapped,
const std::string& header, bool beautify, size_t maxKeyLength) const
{
std::stringstream msg;
std::string spaces;
for (size_t i=0; i<indent; ++i)
spaces = spaces + " ";
// ÇöÀç ³ëµåÀÇ ±íÀÌ¿¡ ¸ÂÃç ÁÖ¼®À» ±â·ÏÇØÁØ´Ù. À¯ÀÇÇÒ Á¡Àº °ø¹é ¹®Àڷθ¸
// ÀÌ·ç¾îÁø ÁÖ¼®Àº ¾Õ¿¡´Ù '#' ¹®ÀÚ¸¦ Ãâ·ÂÇÏÁö ¾Ê´Â´Ù´Â Á¡ÀÌ´Ù. ±×³É ºó ÁÙÀ»
// Ãâ·ÂÇϱâ À§ÇؼÀÌ´Ù.
if (!m_Comment.empty())
{
std::string comment = m_Comment;
Replace(comment, "\n", std::string("\n" + spaces));
std::string trimmed = Trim(comment, " ");
if (!trimmed.empty() && trimmed[trimmed.size()-1] == '\n')
msg << spaces << comment;
else
msg << spaces << comment << std::endl;
}
if (mapped)
{
msg << spaces << header << m_Key << ":";
if (beautify && m_Key.size() < maxKeyLength && m_SequentialChilds.empty())
msg << std::string(maxKeyLength - m_Key.size(), ' ');
std::string value(m_Value);
switch (m_ScalarType)
{
case NORMAL_SCALAR:
msg << " " << value << std::endl;
break;
case BLOCK_SCALAR:
msg << " |" << std::endl;
for (SCALARS::const_iterator itr(m_Scalars.begin());
itr != m_Scalars.end(); ++itr)
{
msg << spaces << " " << *itr << std::endl;
}
break;
case FOLDED_SCALAR:
msg << " >" << std::endl;
for (SCALARS::const_iterator itr(m_Scalars.begin());
itr != m_Scalars.end(); ++itr)
{
msg << spaces << " " << *itr << std::endl;
}
break;
default:
msg << spaces << m_Key << ": " << value << std::endl;
break;
}
if (m_ChildType == CHILD_MAPPED)
{
size_t size = m_SequentialChilds.size();
for (size_t i=0; i<size; ++i)
{
const cYamlTree* const child = m_SequentialChilds[i];
if (header.empty())
msg << child->ToString(indent + 2, true, "", beautify, m_MaxChildKeyLength);
else
msg << child->ToString(indent + 3, true, "", beautify, m_MaxChildKeyLength);
}
}
else if (m_ChildType == CHILD_SEQNENTIAL)
{
size_t size = m_SequentialChilds.size();
for (size_t i=0; i<size; ++i)
{
const cYamlTree* const child = m_SequentialChilds[i];
if (header.empty())
msg << child->ToString(indent + 1, true, "", beautify, m_MaxChildKeyLength);
else
msg << child->ToString(indent + 2, true, "", beautify, m_MaxChildKeyLength);
}
}
}
else
{
bool first = true;
bool childMapped = m_ChildType == CHILD_MAPPED;
size_t size = m_SequentialChilds.size();
for (size_t i=0; i<size; ++i)
{
const cYamlTree* const child = m_SequentialChilds[i];
if (first)
{
msg << child->ToString(indent, childMapped, "- ", beautify, m_MaxChildKeyLength);
first = false;
}
else
{
msg << child->ToString(indent + 1, childMapped, "", beautify, m_MaxChildKeyLength);
}
}
}
return msg.str();
}
////////////////////////////////////////////////////////////////////////////////
/// \brief »ý¼ºÀÚ
////////////////////////////////////////////////////////////////////////////////
cYamlDocument::cYamlDocument()
: cYamlTree()
{
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ¼Ò¸êÀÚ
////////////////////////////////////////////////////////////////////////////////
cYamlDocument::~cYamlDocument()
{
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ¾ÞÄ¿¸¦ Ãß°¡ÇÑ´Ù.
/// \param name ¾ÞÄ¿ À̸§
/// \param tree ¾ÞÄ¿ÀÇ ´ë»óÀÌ µÇ´Â Æ®¸®
////////////////////////////////////////////////////////////////////////////////
void cYamlDocument::AddAnchor(const std::string& name, cYamlTree* tree)
{
if (!name.empty())
m_Anchors[name] = tree;
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÇØ´çÇÏ´Â À̸§ÀÇ ¾ÞÄ¿¸¦ ¹ÝȯÇÑ´Ù.
/// \param name ¾ÞÄ¿ À̸§
/// \return cYamlTree* ÇØ´çÇÏ´Â Æ®¸®°¡ Á¸ÀçÇÏ´Â °æ¿ì ±× Æ®¸®¸¦ ¹ÝȯÇϰí,
/// Á¸ÀçÇÏÁö ¾Ê´Â °æ¿ì¿¡´Â NULLÀ» ¹ÝȯÇÑ´Ù.
////////////////////////////////////////////////////////////////////////////////
cYamlTree* cYamlDocument::GetAnchor(const std::string& name) const
{
ANCHORS::const_iterator itr(m_Anchors.find(name));
return itr != m_Anchors.end() ? itr->second : NULL;
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ¸ðµç ¾ÞÄ¿¸¦ »èÁ¦ÇÑ´Ù.
////////////////////////////////////////////////////////////////////////////////
void cYamlDocument::ClearAnchors()
{
m_Anchors.clear();
}
////////////////////////////////////////////////////////////////////////////////
/// \brief YAML ÆÄÀÏ¿¡¼ µ¥ÀÌÅ͸¦ Àоîµé¿© µ¥ÀÌÅ͸¦ ±¸¼ºÇÑ´Ù.
/// \param fileName ÆÄÀÏ À̸§
/// \return bool ÆÄÀÏÀ» ¹«»çÈ÷ ÀоîµéÀÎ °æ¿ì true, ¹º°¡ ¿¡·¯°¡ »ý±ä °æ¿ì¿¡´Â
/// false¸¦ ¹ÝȯÇÑ´Ù. ¿¡·¯°¡ »ý±ä °æ¿ì¿¡´Â std::cerrÀ» ÀÌ¿ëÇØ ¿¡·¯ ¸Þ½ÃÁö°¡
/// Ãâ·ÂµÈ´Ù.
////////////////////////////////////////////////////////////////////////////////
bool cYamlDocument::Load(const char* fileName)
{
Clear();
ClearAnchors();
cYamlStream stream(fileName, this);
if (!stream.IsGood())
{
char buf[1024] = {0,};
#if _MSC_VER >= 1400
_snprintf_s(buf, sizeof(buf)-1, _TRUNCATE, "cannot open %s", fileName);
#else
sprintf(buf, "cannot open %s", fileName);
#endif
buf[sizeof(buf)-1] = 0;
m_LastError = buf;
return false;
}
std::vector<STATE> stateStack;
stateStack.push_back(STATE(this, -1));
bool result = true;
ParseMode mode = MODE_NORMAL;
cYamlTree* lastChild = NULL;
try
{
while (stream.IsGood())
{
// ½ºÅÃÀÌ ºñ¾ú´Ù´Â ¸»Àº, AdoptChild ÇÔ¼ö¿¡¼
// ¿Ã¹Ù¸¥ parent¸¦ ã´Ù°¡ °á±¹ ¸ø ã¾Ò´Ù´Â À̾߱â´Ù.
// ±×·¯¹Ç·Î ÀÌ´Â Àε§Æ® ¿¡·¯´Ù.
if (stateStack.empty())
throw std::string("indent error");
if (stream.ParseNextLine(mode == MODE_NORMAL) != RESULT_NORMAL)
continue; // ÁÖ¼®À̶ó¸é ÆÐ½º~
int indent = stream.GetIndent();
STATE& top = stateStack.back();
// YAMLÀº ¹«Á¶°Ç Ä÷³ 0ºÎÅÍ ½ÃÀÛÇÒ Çʿ䰡 ¾ø±â ¶§¹®¿¡,
// ·çÆ® ³ëµå°¡ Ä÷³ 0¿¡ Á¸ÀçÇÑ´Ù°í °¡Á¤ÇÏ¸é °ï¶õÇÏ´Ù.
// Á¦ÀÏ Ã³À½¿¡ ³ëµå°¡ ³ª¿À´Â Ä÷³À» ·çÆ® ³ëµåÀÇ Ä÷³À¸·Î Àâ´Â´Ù.
if (top.indent == -1) { top.indent = indent; }
//------------------------------------------------------------------
// ÇÑ ¶óÀξ¿ ó¸® Áß
//------------------------------------------------------------------
if (mode == MODE_NORMAL)
{
if (top.indent == indent) // ÅÇÀÌ ÀÌÀü ³ëµå¿Í °°´Ù.
{
//cYamlTree* child = stream.CreateTree();
//lastChild = top.node->AddChild(child);
/// ºÎ¸ð ³ëµå°¡ aliasµÈ ³ëµå¶ó¸é °ï¶õÇÏ´Ù.
if (top.node->GetAlias())
{
std::string msg("cannot add child node to aliased node ");
throw (msg + top.node->GetKey());
}
cYamlTree* child = stream.CreateTree();
if (child->GetChildCount() == 0 || child->GetAlias())
{
lastChild = top.node->AddChild(child);
}
else
{
top.node->AddChild(child);
stateStack.push_back(STATE(child, stream.GetIndent()));
lastChild = child->GetChild(0);
}
}
else if (top.indent < indent) // ÅÇÀÌ ´Ã¾î³µ´Ù.
{
if (lastChild == NULL)
throw std::string("indent error");
/// ºÎ¸ð ³ëµå°¡ aliasµÈ ³ëµå¶ó¸é °ï¶õÇÏ´Ù.
if (lastChild->GetAlias())
{
std::string msg("cannot add child node to aliased node ");
throw (msg + lastChild->GetKey());
}
stateStack.push_back(STATE(lastChild, indent));
cYamlTree* child = stream.CreateTree();
if (child->GetChildCount() == 0 || child->GetAlias())
{
lastChild = lastChild->AddChild(child);
}
else
{
stateStack.push_back(STATE(child, stream.GetIndent()));
lastChild->AddChild(child);
lastChild = child->GetChild(0);
}
}
else if (indent < top.indent) // ÅÇÀÌ ÁÙ¾îµé¾ú´Ù.
{
cYamlTree* child = stream.CreateTree();
if (child->GetChildCount() == 0 || child->GetAlias())
{
lastChild = AdoptChild(stateStack, indent, child);
}
else
{
AdoptChild(stateStack, indent, child);
stateStack.push_back(STATE(child, stream.GetIndent()));
lastChild = child->GetChild(0);
}
}
mode = stream.GetNextMode();
}
//------------------------------------------------------------------
// ¿©·¯ Çà¿¡ °ÉÄ£ °ª ó¸® Áß
//------------------------------------------------------------------
else
{
if (top.indent == indent) // ÅÇÀÌ ÀÌÀü ³ëµå¿Í °°´Ù.
{
if (stream.IsEmptyLine()) continue;
cYamlTree* child = stream.CreateTree();
lastChild = top.node->AddChild(child);
mode = stream.GetNextMode();
}
else if (top.indent < indent) // ÅÇÀÌ ´Ã¾î³µ´Ù.
{
std::string trimmed(Trim(stream.GetText()));
if (mode == MODE_BLOCK_SCALAR)
{
lastChild->SetValue(lastChild->GetValue() + "\n" + trimmed);
lastChild->SetScalarType(cYamlTree::BLOCK_SCALAR);
lastChild->AddScalar(trimmed);
}
else if (mode == MODE_FOLDED_SCALAR)
{
lastChild->SetValue(lastChild->GetValue() +
" " + trimmed);
lastChild->SetScalarType(cYamlTree::FOLDED_SCALAR);
lastChild->AddScalar(trimmed);
}
}
else if (indent < top.indent) // ÅÇÀÌ ÁÙ¾îµé¾ú´Ù.
{
// ÅÇÀÌ ÁÙ¾îµé¾ú´Ù°í ÇØµµ, Ä¿¸àÆ® ¶óÀÎÀ̶ó¸é ÆÐ½º
if (stream.IsEmptyLine()) continue;
lastChild = AdoptChild(stateStack, indent, stream.CreateTree());
mode = stream.GetNextMode();
}
}
}
}
catch (std::string& e)
{
char buf[1024] = {0, };
#if _MSC_VER >= 1400
_snprintf_s(buf, sizeof(buf), _TRUNCATE,
"%s:%d: %s", fileName, stream.GetCurrentLine(), e.c_str());
#else
sprintf(buf,
"%s:%d: %s", fileName, stream.GetCurrentLine(), e.c_str());
#endif
buf[sizeof(buf)-1] = 0;
m_LastError = buf;
if (s_ParseErrorHandler)
s_ParseErrorHandler(m_LastError.c_str());
result = false;
}
return result;
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ³»ºÎ µ¥ÀÌÅ͸¦ ÆÄÀÏ¿¡´Ù ÀúÀåÇÑ´Ù.
/// \param fileName ÆÄÀÏ À̸§
/// \param beautify Ãâ·Â ÆÄÀÏÀÇ Àε§Æ®¸¦ ¿¹»Ú°Ô Á¤·ÄÇÒ °ÍÀΰ¡ÀÇ ¿©ºÎ
/// \return bool ÀúÀå¿¡ ¼º°øÇÑ °æ¿ì true, ÆÄÀÏÀ» ¾²±â¿ëÀ¸·Î ¿Áö ¸øÇß´Ù¸é false
////////////////////////////////////////////////////////////////////////////////
bool cYamlDocument::Save(const char* fileName, bool beautify) const
{
std::ofstream file(fileName, std::ios::out | std::ios::trunc);
if (!file) return false;
file << ToString(beautify, false) << std::endl;
return true;
}
#ifdef D3DX_VERSION
////////////////////////////////////////////////////////////////////////////////
/// \brief »ý¼ºÀÚ
/// \param key Ű
/// \param value °ª
////////////////////////////////////////////////////////////////////////////////
cYamlTree::cYamlTree(const std::string& key, const D3DXVECTOR2& value)
: m_Key(key), m_ScalarType(NORMAL_SCALAR), m_Alias(NULL),
m_ChildType(CHILD_UNKNOWN), m_MaxChildKeyLength(0)
{
SetValue(value);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief »ý¼ºÀÚ
/// \param key Ű
/// \param value °ª
////////////////////////////////////////////////////////////////////////////////
cYamlTree::cYamlTree(const std::string& key, const D3DXVECTOR3& value)
: m_Key(key), m_ScalarType(NORMAL_SCALAR), m_Alias(NULL),
m_ChildType(CHILD_UNKNOWN), m_MaxChildKeyLength(0)
{
SetValue(value);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief »ý¼ºÀÚ
/// \param key Ű
/// \param value °ª
////////////////////////////////////////////////////////////////////////////////
cYamlTree::cYamlTree(const std::string& key, const D3DXVECTOR4& value)
: m_Key(key), m_ScalarType(NORMAL_SCALAR), m_Alias(NULL),
m_ChildType(CHILD_UNKNOWN), m_MaxChildKeyLength(0)
{
SetValue(value);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief »ý¼ºÀÚ
/// \param key Ű
/// \param value °ª
////////////////////////////////////////////////////////////////////////////////
cYamlTree::cYamlTree(const std::string& key, const D3DXQUATERNION& value)
: m_Key(key), m_ScalarType(NORMAL_SCALAR), m_Alias(NULL),
m_ChildType(CHILD_UNKNOWN), m_MaxChildKeyLength(0)
{
SetValue(value);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief »ý¼ºÀÚ
/// \param key Ű
/// \param value °ª
////////////////////////////////////////////////////////////////////////////////
cYamlTree::cYamlTree(const std::string& key, const D3DXCOLOR& value)
: m_Key(key), m_ScalarType(NORMAL_SCALAR), m_Alias(NULL),
m_ChildType(CHILD_UNKNOWN), m_MaxChildKeyLength(0)
{
SetValue(value);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ³ëµåÀÇ °ªÀ» D3DXVECTOR2 ÇüÅ·Π¹ÝȯÇÑ´Ù.
/// \return D3DXVECTOR2 °ª
////////////////////////////////////////////////////////////////////////////////
D3DXVECTOR2 cYamlTree::GetValueAsVector2() const
{
char text[256] = {0, };
#if _MSC_VER >= 1400
strcpy_s(text, sizeof(text), m_Value.c_str());
#else
strcpy(text, m_Value.c_str());
#endif
float value[2] = {0.0f, };
int count = 0;
char* token = NULL;
#if _MSC_VER >= 1400
char* context = NULL;
token = strtok_s(text, ", \t", &context);
#else
token = strtok(text, ", \t");
#endif
while (token && count < 2)
{
value[count++] = static_cast<float>(atof(token));
#if _MSC_VER >= 1400
token = strtok_s(NULL, ", \t", &context);
#else
token = strtok(text, ", \t");
#endif
}
return D3DXVECTOR2(value);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ³ëµåÀÇ °ªÀ» D3DXVECTOR3 ÇüÅ·Π¹ÝȯÇÑ´Ù.
/// \return D3DXVECTOR3 °ª
////////////////////////////////////////////////////////////////////////////////
D3DXVECTOR3 cYamlTree::GetValueAsVector3() const
{
char text[256] = {0, };
#if _MSC_VER >= 1400
strcpy_s(text, sizeof(text), m_Value.c_str());
#else
strcpy(text, m_Value.c_str());
#endif
float value[3] = {0.0f, };
int count = 0;
char* token = NULL;
#if _MSC_VER >= 1400
char* context = NULL;
token = strtok_s(text, ", \t", &context);
#else
token = strtok(text, ", \t");
#endif
while (token && count < 3)
{
value[count++] = static_cast<float>(atof(token));
#if _MSC_VER >= 1400
token = strtok_s(NULL, ", \t", &context);
#else
token = strtok(text, ", \t");
#endif
}
return D3DXVECTOR3(value);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ³ëµåÀÇ °ªÀ» D3DXVECTOR4 ÇüÅ·Π¹ÝȯÇÑ´Ù.
/// \return D3DXVECTOR4 °ª
////////////////////////////////////////////////////////////////////////////////
D3DXVECTOR4 cYamlTree::GetValueAsVector4() const
{
char text[256] = {0, };
#if _MSC_VER >= 1400
strcpy_s(text, sizeof(text), m_Value.c_str());
#else
strcpy(text, m_Value.c_str());
#endif
float value[4] = {0.0f, };
int count = 0;
char* token = NULL;
#if _MSC_VER >= 1400
char* context = NULL;
token = strtok_s(text, ", \t", &context);
#else
token = strtok(text, ", \t");
#endif
while (token && count < 4)
{
value[count++] = static_cast<float>(atof(token));
#if _MSC_VER >= 1400
token = strtok_s(NULL, ", \t", &context);
#else
token = strtok(text, ", \t");
#endif
}
return D3DXVECTOR4(value);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ³ëµåÀÇ °ªÀ» D3DXQUATERNION ÇüÅ·Π¹ÝȯÇÑ´Ù.
/// \return D3DXQUATERNION °ª
////////////////////////////////////////////////////////////////////////////////
D3DXQUATERNION cYamlTree::GetValueAsQuaternion() const
{
char text[256] = {0, };
#if _MSC_VER >= 1400
strcpy_s(text, sizeof(text), m_Value.c_str());
#else
strcpy(text, m_Value.c_str());
#endif
float value[4] = {0.0f, };
int count = 0;
char* token = NULL;
#if _MSC_VER >= 1400
char* context = NULL;
token = strtok_s(text, ", \t", &context);
#else
token = strtok(text, ", \t");
#endif
while (token && count < 4)
{
value[count++] = static_cast<float>(atof(token));
#if _MSC_VER >= 1400
token = strtok_s(NULL, ", \t", &context);
#else
token = strtok(text, ", \t");
#endif
}
return D3DXQUATERNION(value);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ³ëµåÀÇ °ªÀ» D3DXCOLOR ÇüÅ·Π¹ÝȯÇÑ´Ù.
/// \return D3DXCOLOR °ª
////////////////////////////////////////////////////////////////////////////////
D3DXCOLOR cYamlTree::GetValueAsColor() const
{
char text[256] = {0, };
#if _MSC_VER >= 1400
strcpy_s(text, sizeof(text), m_Value.c_str());
#else
strcpy(text, m_Value.c_str());
#endif
unsigned char value[4] = {0, };
int count = 0;
char* token = NULL;
#if _MSC_VER >= 1400
char* context = NULL;
token = strtok_s(text, ", \t", &context);
#else
token = strtok(text, ", \t");
#endif
while (token && count < 4)
{
value[count++] = (unsigned char)atoi(token);
#if _MSC_VER >= 1400
token = strtok_s(NULL, ", \t", &context);
#else
token = strtok(text, ", \t");
#endif
}
return D3DXCOLOR(D3DCOLOR_RGBA(value[0], value[1], value[2], value[3]));
}
////////////////////////////////////////////////////////////////////////////////
/// \brief D3DXVECTOR2 ÇüÅ·Π°ªÀ» ¼³Á¤ÇÑ´Ù.
/// \param value ¼³Á¤ÇÒ °ª
////////////////////////////////////////////////////////////////////////////////
void cYamlTree::SetValue(const D3DXVECTOR2& value)
{
char buf[256] = {0, };
#if _MSC_VER >= 1400
_snprintf_s(buf, sizeof(buf)-1, _TRUNCATE, "%f, %f", value.x, value.y);
#else
sprintf(buf, "%f, %f", value.x, value.y);
#endif
buf[sizeof(buf)-1] = 0;
SetValue(buf);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief D3DXVECTOR3 ÇüÅ·Π°ªÀ» ¼³Á¤ÇÑ´Ù.
/// \param value ¼³Á¤ÇÒ °ª
////////////////////////////////////////////////////////////////////////////////
void cYamlTree::SetValue(const D3DXVECTOR3& value)
{
char buf[256] = {0, };
#if _MSC_VER >= 1400
_snprintf_s(buf, sizeof(buf)-1, _TRUNCATE, "%f, %f, %f",
value.x, value.y, value.z);
#else
sprintf(buf, "%f, %f, %f",
value.x, value.y, value.z);
#endif
buf[sizeof(buf)-1] = 0;
SetValue(buf);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief D3DXVECTOR4 ÇüÅ·Π°ªÀ» ¼³Á¤ÇÑ´Ù.
/// \param value ¼³Á¤ÇÒ °ª
////////////////////////////////////////////////////////////////////////////////
void cYamlTree::SetValue(const D3DXVECTOR4& value)
{
char buf[256] = {0, };
#if _MSC_VER >= 1400
_snprintf_s(buf, sizeof(buf)-1, _TRUNCATE, "%f, %f, %f, %f",
value.x, value.y, value.z, value.w);
#else
sprintf(buf, "%f, %f, %f, %f",
value.x, value.y, value.z, value.w);
#endif
buf[sizeof(buf)-1] = 0;
SetValue(buf);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief D3DXQUATERNION ÇüÅ·Π°ªÀ» ¼³Á¤ÇÑ´Ù.
/// \param value ¼³Á¤ÇÒ °ª
////////////////////////////////////////////////////////////////////////////////
void cYamlTree::SetValue(const D3DXQUATERNION& value)
{
char buf[256] = {0, };
#if _MSC_VER >= 1400
_snprintf_s(buf, sizeof(buf)-1, _TRUNCATE, "%f, %f, %f, %f",
value.x, value.y, value.z, value.w);
#else
sprintf(buf, "%f, %f, %f, %f",
value.x, value.y, value.z, value.w);
#endif
buf[sizeof(buf)-1] = 0;
SetValue(buf);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief D3DXCOLOR ÇüÅ·Π°ªÀ» ¼³Á¤ÇÑ´Ù.
/// \param value ¼³Á¤ÇÒ °ª
////////////////////////////////////////////////////////////////////////////////
void cYamlTree::SetValue(const D3DXCOLOR& value)
{
char buf[256] = {0, };
#if _MSC_VER >= 1400
_snprintf_s(buf, sizeof(buf)-1, _TRUNCATE, "%d, %d, %d, %d",
(int)(value.r * 255), (int)(value.g * 255), (int)(value.b * 255), (int)(value.a * 255));
#else
sprintf(buf, "%d, %d, %d, %d",
(int)(value.r * 255), (int)(value.g * 255), (int)(value.b * 255), (int)(value.a * 255));
#endif
buf[sizeof(buf)-1] = 0;
SetValue(buf);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå¸¦ ã¾Æ, ±× ³ëµåÀÇ ÅØ½ºÆ® °ªÀ»
/// D3DXVECTOR2 ÇüÅ·Π¹ÝȯÇÑ´Ù.
/// \param key Ű
/// \return D3DXVECTOR2 ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå°¡ ÀÖ´Ù¸é ±× ³ëµåÀÇ °ªÀ»
/// ¹ÝȯÇϰí, ¾ø´Ù¸é 0.0f ¹è¿À» ¹ÝȯÇÑ´Ù.
/// \note ÇØ´çÇÏ´Â ÀÚ½Ä ³ëµå°¡ ¾ø´Â °æ¿ì, µð¹ö±× ¹öÀü¿¡¼´Â ¾î¼Æ®¸¦ ¹ß»ý½ÃŲ´Ù.
////////////////////////////////////////////////////////////////////////////////
D3DXVECTOR2 cYamlTree::AttrAsVector2(const std::string& key) const
{
cYamlTree* child = GetChild(key, true);
return child ?
child->GetValueAsVector2() : D3DXVECTOR2(0.0f, 0.0f);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå¸¦ ã¾Æ, ±× ³ëµåÀÇ ÅØ½ºÆ® °ªÀ»
/// D3DXVECTOR3 ÇüÅ·Π¹ÝȯÇÑ´Ù.
/// \param key Ű
/// \return D3DXVECTOR3 ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå°¡ ÀÖ´Ù¸é ±× ³ëµåÀÇ °ªÀ»
/// ¹ÝȯÇϰí, ¾ø´Ù¸é 0.0f ¹è¿À» ¹ÝȯÇÑ´Ù.
/// \note ÇØ´çÇÏ´Â ÀÚ½Ä ³ëµå°¡ ¾ø´Â °æ¿ì, µð¹ö±× ¹öÀü¿¡¼´Â ¾î¼Æ®¸¦ ¹ß»ý½ÃŲ´Ù.
////////////////////////////////////////////////////////////////////////////////
D3DXVECTOR3 cYamlTree::AttrAsVector3(const std::string& key) const
{
cYamlTree* child = GetChild(key, true);
return child ?
child->GetValueAsVector3() : D3DXVECTOR3(0.0f, 0.0f, 0.0f);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå¸¦ ã¾Æ, ±× ³ëµåÀÇ ÅØ½ºÆ® °ªÀ»
/// D3DXVECTOR4 ÇüÅ·Π¹ÝȯÇÑ´Ù.
/// \param key Ű
/// \return D3DXVECTOR4 ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå°¡ ÀÖ´Ù¸é ±× ³ëµåÀÇ °ªÀ»
/// ¹ÝȯÇϰí, ¾ø´Ù¸é 0.0f ¹è¿À» ¹ÝȯÇÑ´Ù.
/// \note ÇØ´çÇÏ´Â ÀÚ½Ä ³ëµå°¡ ¾ø´Â °æ¿ì, µð¹ö±× ¹öÀü¿¡¼´Â ¾î¼Æ®¸¦ ¹ß»ý½ÃŲ´Ù.
////////////////////////////////////////////////////////////////////////////////
D3DXVECTOR4 cYamlTree::AttrAsVector4(const std::string& key) const
{
cYamlTree* child = GetChild(key, true);
return child ?
child->GetValueAsVector4() : D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå¸¦ ã¾Æ, ±× ³ëµåÀÇ ÅØ½ºÆ® °ªÀ»
/// D3DXQUATERNION ÇüÅ·Π¹ÝȯÇÑ´Ù.
/// \param key Ű
/// \return D3DXQUATERNION ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå°¡ ÀÖ´Ù¸é ±× ³ëµåÀÇ °ªÀ»
/// ¹ÝȯÇϰí, ¾ø´Ù¸é 0.0f ¹è¿À» ¹ÝȯÇÑ´Ù.
/// \note ÇØ´çÇÏ´Â ÀÚ½Ä ³ëµå°¡ ¾ø´Â °æ¿ì, µð¹ö±× ¹öÀü¿¡¼´Â ¾î¼Æ®¸¦ ¹ß»ý½ÃŲ´Ù.
////////////////////////////////////////////////////////////////////////////////
D3DXQUATERNION cYamlTree::AttrAsQuaternion(const std::string& key) const
{
cYamlTree* child = GetChild(key, true);
return child ?
child->GetValueAsQuaternion() : D3DXQUATERNION(0.0f, 0.0f, 0.0f, 0.0f);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå¸¦ ã¾Æ, ±× ³ëµåÀÇ ÅØ½ºÆ® °ªÀ»
/// D3DXCOLOR ÇüÅ·Π¹ÝȯÇÑ´Ù.
/// \param key Ű
/// \return D3DXCOLOR ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå°¡ ÀÖ´Ù¸é ±× ³ëµåÀÇ °ªÀ»
/// ¹ÝȯÇϰí, ¾ø´Ù¸é 0.0f ¹è¿À» ¹ÝȯÇÑ´Ù.
/// \note ÇØ´çÇÏ´Â ÀÚ½Ä ³ëµå°¡ ¾ø´Â °æ¿ì, µð¹ö±× ¹öÀü¿¡¼´Â ¾î¼Æ®¸¦ ¹ß»ý½ÃŲ´Ù.
////////////////////////////////////////////////////////////////////////////////
D3DXCOLOR cYamlTree::AttrAsColor(const std::string& key) const
{
cYamlTree* child = GetChild(key, true);
return child ?
child->GetValueAsColor() : D3DXCOLOR(0.0f, 0.0f, 0.0f, 0.0f);
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå¸¦ ã¾Æ, ±× ³ëµåÀÇ ÅØ½ºÆ® °ªÀ»
/// D3DXVECTOR2 ÇüÅ·Π¹ÝȯÇÑ´Ù.
/// \param key Ű
/// \param nullValue ÇØ´çÇÏ´Â ÀÚ½Ä ³ëµå°¡ Á¸ÀçÇÏÁö ¾ÊÀ» °æ¿ì¿¡ ¹ÝȯÇÒ °ª
/// \return D3DXVECTOR2 ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå°¡ ÀÖ´Ù¸é ±× ³ëµåÀÇ °ªÀ»
/// ¹ÝȯÇϰí, ¾ø´Ù¸é ÁÖ¾îÁø nullValue¸¦ ¹ÝȯÇÑ´Ù.
////////////////////////////////////////////////////////////////////////////////
D3DXVECTOR2 cYamlTree::AttrAsVector2Safe(const std::string& key, const D3DXVECTOR2& nullValue) const
{
cYamlTree* child = GetChild(key, false);
return child ? child->GetValueAsVector2() : nullValue;
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå¸¦ ã¾Æ, ±× ³ëµåÀÇ ÅØ½ºÆ® °ªÀ»
/// D3DXVECTOR3 ÇüÅ·Π¹ÝȯÇÑ´Ù.
/// \param key Ű
/// \param nullValue ÇØ´çÇÏ´Â ÀÚ½Ä ³ëµå°¡ Á¸ÀçÇÏÁö ¾ÊÀ» °æ¿ì¿¡ ¹ÝȯÇÒ °ª
/// \return D3DXVECTOR3 ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå°¡ ÀÖ´Ù¸é ±× ³ëµåÀÇ °ªÀ»
/// ¹ÝȯÇϰí, ¾ø´Ù¸é ÁÖ¾îÁø nullValue¸¦ ¹ÝȯÇÑ´Ù.
////////////////////////////////////////////////////////////////////////////////
D3DXVECTOR3 cYamlTree::AttrAsVector3Safe(const std::string& key, const D3DXVECTOR3& nullValue) const
{
cYamlTree* child = GetChild(key, false);
return child ? child->GetValueAsVector3() : nullValue;
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå¸¦ ã¾Æ, ±× ³ëµåÀÇ ÅØ½ºÆ® °ªÀ»
/// D3DXVECTOR4 ÇüÅ·Π¹ÝȯÇÑ´Ù.
/// \param key Ű
/// \param nullValue ÇØ´çÇÏ´Â ÀÚ½Ä ³ëµå°¡ Á¸ÀçÇÏÁö ¾ÊÀ» °æ¿ì¿¡ ¹ÝȯÇÒ °ª
/// \return D3DXVECTOR4 ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå°¡ ÀÖ´Ù¸é ±× ³ëµåÀÇ °ªÀ»
/// ¹ÝȯÇϰí, ¾ø´Ù¸é ÁÖ¾îÁø nullValue¸¦ ¹ÝȯÇÑ´Ù.
////////////////////////////////////////////////////////////////////////////////
D3DXVECTOR4 cYamlTree::AttrAsVector4Safe(const std::string& key, const D3DXVECTOR4& nullValue) const
{
cYamlTree* child = GetChild(key, false);
return child ? child->GetValueAsVector4() : nullValue;
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå¸¦ ã¾Æ, ±× ³ëµåÀÇ ÅØ½ºÆ® °ªÀ»
/// D3DXQUATERNION ÇüÅ·Π¹ÝȯÇÑ´Ù.
/// \param key Ű
/// \param nullValue ÇØ´çÇÏ´Â ÀÚ½Ä ³ëµå°¡ Á¸ÀçÇÏÁö ¾ÊÀ» °æ¿ì¿¡ ¹ÝȯÇÒ °ª
/// \return D3DXQUATERNION ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå°¡ ÀÖ´Ù¸é ±× ³ëµåÀÇ °ªÀ»
/// ¹ÝȯÇϰí, ¾ø´Ù¸é ÁÖ¾îÁø nullValue¸¦ ¹ÝȯÇÑ´Ù.
////////////////////////////////////////////////////////////////////////////////
D3DXQUATERNION cYamlTree::AttrAsQuaternionSafe(const std::string& key, const D3DXQUATERNION& nullValue) const
{
cYamlTree* child = GetChild(key, false);
return child ? child->GetValueAsQuaternion() : nullValue;
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå¸¦ ã¾Æ, ±× ³ëµåÀÇ ÅØ½ºÆ® °ªÀ»
/// D3DXCOLOR ÇüÅ·Π¹ÝȯÇÑ´Ù.
/// \param key Ű
/// \param nullValue ÇØ´çÇÏ´Â ÀÚ½Ä ³ëµå°¡ Á¸ÀçÇÏÁö ¾ÊÀ» °æ¿ì¿¡ ¹ÝȯÇÒ °ª
/// \return D3DXCOLOR ÇØ´çÇϴ Ű¸¦ °¡Áø ÀÚ½Ä ³ëµå°¡ ÀÖ´Ù¸é ±× ³ëµåÀÇ °ªÀ»
/// ¹ÝȯÇϰí, ¾ø´Ù¸é ÁÖ¾îÁø nullValue¸¦ ¹ÝȯÇÑ´Ù.
////////////////////////////////////////////////////////////////////////////////
D3DXCOLOR cYamlTree::AttrAsColorSafe(const std::string& key, const D3DXCOLOR& nullValue) const
{
cYamlTree* child = GetChild(key, false);
return child ? child->GetValueAsColor() : nullValue;
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÀÚ½Ä ³ëµå¸¦ Ãß°¡ÇÑ´Ù.
/// \param key Ű
/// \param value °ª
/// \return cYamlTree* Ãß°¡ÇÑ ÀÚ½Ä ³ëµåÀÇ Æ÷ÀÎÅÍ
////////////////////////////////////////////////////////////////////////////////
cYamlTree* cYamlTree::AddAttr(const std::string& key, const D3DXVECTOR2& value)
{
return AddChild(new cYamlTree(key, value));
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÀÚ½Ä ³ëµå¸¦ Ãß°¡ÇÑ´Ù.
/// \param key Ű
/// \param value °ª
/// \return cYamlTree* Ãß°¡ÇÑ ÀÚ½Ä ³ëµåÀÇ Æ÷ÀÎÅÍ
////////////////////////////////////////////////////////////////////////////////
cYamlTree* cYamlTree::AddAttr(const std::string& key, const D3DXVECTOR3& value)
{
return AddChild(new cYamlTree(key, value));
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÀÚ½Ä ³ëµå¸¦ Ãß°¡ÇÑ´Ù.
/// \param key Ű
/// \param value °ª
/// \return cYamlTree* Ãß°¡ÇÑ ÀÚ½Ä ³ëµåÀÇ Æ÷ÀÎÅÍ
////////////////////////////////////////////////////////////////////////////////
cYamlTree* cYamlTree::AddAttr(const std::string& key, const D3DXVECTOR4& value)
{
return AddChild(new cYamlTree(key, value));
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÀÚ½Ä ³ëµå¸¦ Ãß°¡ÇÑ´Ù.
/// \param key Ű
/// \param value °ª
/// \return cYamlTree* Ãß°¡ÇÑ ÀÚ½Ä ³ëµåÀÇ Æ÷ÀÎÅÍ
////////////////////////////////////////////////////////////////////////////////
cYamlTree* cYamlTree::AddAttr(const std::string& key, const D3DXQUATERNION& value)
{
return AddChild(new cYamlTree(key, value));
}
////////////////////////////////////////////////////////////////////////////////
/// \brief ÀÚ½Ä ³ëµå¸¦ Ãß°¡ÇÑ´Ù.
/// \param key Ű
/// \param value °ª
/// \return cYamlTree* Ãß°¡ÇÑ ÀÚ½Ä ³ëµåÀÇ Æ÷ÀÎÅÍ
////////////////////////////////////////////////////////////////////////////////
cYamlTree* cYamlTree::AddAttr(const std::string& key, const D3DXCOLOR& value)
{
return AddChild(new cYamlTree(key, value));
}
#endif
3 »ùÇÃ
¾Æ·¡¿Í °°Àº YAML ÆÄÀÏÀÌ ÀÖ´Ù¸é.
invoice: 34843
date : 2001-01-23
bill-to: &id001
given : Chris
family : Dumars
address:
lines: |
458 Walkman Dr.
Suite #292
city : Royal Oak
state : MI
postal : 48046
ship-to: *id001
product:
- sku : BL394D4
quantity : 4
description : Basketball
price : 450.00
- sku : BL4438H
quantity : 1
description : Super Hoop
price : 2392.00
´ÙÀ½°ú °°Àº ¹æ½ÄÀ¸·Î ÀоîµéÀÏ ¼ö ÀÖ´Ù.
cYamlDocument document;
if (!document.Load("test.yaml"))
{
std::cerr << document.GetLastError() << std::endl;
return -1;
}
std::cout << "Postal: "
<< document.GetChild("bill-to")->GetChild("address")->GetChild("postal")->GetValueAsString()
<< std::endl;
std::cout << "First Product Price"
<< document.GetChild("product")->GetChild(0)->GetChild("Price")->GetValueAsFloat()
<< std::endl;
4 ÁÖÀÇ »çÇ×
5 YAML ¹®¹ý °Ë»ç±â
À§¿¡ ÀÖ´Â ÆÄ¼¸¦ ÀÌ¿ëÇØ¼ ¸¸µç Ä¿¸Çµå ÇÁ·ÒÇÁÆ®¿ë ¹®¹ý °Ë»ç±â. Scite °°Àº ¿¡µðÅÍ¿¡´Ù Ãß°¡Çؼ °£´ÜÇÏ°Ô ¹®¹ýÀ» üũÇÒ ¼ö ÀÖ´Ù.
»ç¿ë¹ý: YAML /¿É¼Ç ¿øº» [´ë»ó]
¿øº»: ¿øº» YAML ÆÄÀÏ À̸§
´ë»ó: ´ë»ó YAML ÆÄÀÏ À̸§ ¶Ç´Â Ű ¹®ÀÚ¿
¿É¼Ç:
/T: ¹«°á¼º ¿©ºÎ¸¦ °Ë»çÇÕ´Ï´Ù.
/B: Àε§Æ®¸¦ ¾Æ¸§´ä°Ô(-_-) ¸¸µì´Ï´Ù. (´ë»ó ÆÄÀÏ ÇÊ¿ä)
/E: ´ë»óÀ¸·Î ÁÖ¾îÁø ³ëµå¸¦ »Ì¾Æ³»¾î Ç¥ÁØ Ãâ·Â¿¡´Ù Ãâ·ÂÇÕ´Ï´Ù.
»Ì¾Æ³¾ ³ëµå´Â KEY1:KEY2:... ÀÇ Çü½ÄÀ¸·Î ÁöÁ¤ÇÕ´Ï´Ù.
°¢°¢ÀÇ Å°´Â ¹®ÀÚ¿ ¶Ç´Â ¼ýÀÚÀÔ´Ï´Ù.
½ÇÇà ÆÄÀÏ
VisualStudio 2005 ¹öÀü ¼Ò½º
SeriousMoin v1 (koMoinMoin 1.0a4 Modified)