From 489fb7824be1a304d52a7cbac49c9a1ee67714f5 Mon Sep 17 00:00:00 2001 From: natural-law Date: Tue, 14 Jun 2011 14:53:00 +0800 Subject: [PATCH 1/2] fixed #524, Parse the special format of plist files. --- cocos2dx/platform/CCFileUtils.cpp | 105 ++++++++++++++++++++---------- 1 file changed, 71 insertions(+), 34 deletions(-) diff --git a/cocos2dx/platform/CCFileUtils.cpp b/cocos2dx/platform/CCFileUtils.cpp index 14db6e74a5..92efda9519 100644 --- a/cocos2dx/platform/CCFileUtils.cpp +++ b/cocos2dx/platform/CCFileUtils.cpp @@ -44,7 +44,8 @@ typedef enum SAX_DICT, SAX_INT, SAX_REAL, - SAX_STRING + SAX_STRING, + SAX_ARRAY }CCSAXState; class CCDictMaker : public CCSAXDelegator @@ -55,16 +56,17 @@ public: std::stack*> m_tDictStack; std::string m_sCurKey;///< parsed key CCSAXState m_tState; - bool m_bInArray; CCMutableArray *m_pArray; + std::stack*> m_tArrayStack; + std::stack m_tStateStack; + public: CCDictMaker() : m_pRootDict(NULL), m_pCurDict(NULL), m_tState(SAX_NONE), - m_pArray(NULL), - m_bInArray(false) + m_pArray(NULL) { } @@ -91,22 +93,36 @@ public: std::string sName((char*)name); if( sName == "dict" ) { - CCDictionary *pNewDict = new CCDictionary(); + m_pCurDict = new CCDictionary(); if(! m_pRootDict) { - m_pRootDict = pNewDict; - pNewDict->autorelease(); + m_pRootDict = m_pCurDict; } - else - { - CCAssert(m_pCurDict && !m_sCurKey.empty(), ""); - m_pCurDict->setObject(pNewDict, m_sCurKey); - pNewDict->release(); - m_sCurKey.clear(); - } - m_pCurDict = pNewDict; - m_tDictStack.push(m_pCurDict); m_tState = SAX_DICT; + + CCSAXState preState = SAX_NONE; + if (! m_tStateStack.empty()) + { + preState = m_tStateStack.top(); + } + + if (SAX_ARRAY == preState) + { + // add the dictionary into the array + m_pArray->addObject(m_pCurDict); + } + else if (SAX_DICT == preState) + { + // add the dictionary into the pre dictionary + CCAssert(! m_tDictStack.empty(), "The state is wrong!"); + CCDictionary* pPreDict = m_tDictStack.top(); + pPreDict->setObject(m_pCurDict, m_sCurKey); + } + m_pCurDict->autorelease(); + + // record the dict state + m_tStateStack.push(m_tState); + m_tDictStack.push(m_pCurDict); } else if(sName == "key") { @@ -124,44 +140,63 @@ public: { m_tState = SAX_STRING; } + else if (sName == "array") + { + m_tState = SAX_ARRAY; + m_pArray = new CCMutableArray(); + + CCSAXState preState = m_tStateStack.empty() ? SAX_DICT : m_tStateStack.top(); + if (preState == SAX_DICT) + { + m_pCurDict->setObject(m_pArray, m_sCurKey); + } + else if (preState == SAX_ARRAY) + { + CCAssert(! m_tArrayStack.empty(), "The state is worng!"); + CCMutableArray* pPreArray = m_tArrayStack.top(); + pPreArray->addObject(m_pArray); + } + m_pArray->release(); + // record the array state + m_tStateStack.push(m_tState); + m_tArrayStack.push(m_pArray); + } else { - if (sName == "array") - { - m_bInArray = true; - m_pArray = new CCMutableArray(); - } m_tState = SAX_NONE; } } void endElement(void *ctx, const char *name) { + CCSAXState curState = m_tStateStack.empty() ? SAX_DICT : m_tStateStack.top(); std::string sName((char*)name); if( sName == "dict" ) { + m_tStateStack.pop(); m_tDictStack.pop(); - if ( !m_tDictStack.empty() ) + if ( !m_tDictStack.empty()) { - m_pCurDict = (CCDictionary*)(m_tDictStack.top()); + m_pCurDict = m_tDictStack.top(); } } else if (sName == "array") { - CCAssert(m_bInArray, "The plist file is wrong!"); - m_pCurDict->setObject(m_pArray, m_sCurKey); - m_pArray->release(); - m_pArray = NULL; - m_bInArray = false; + m_tStateStack.pop(); + m_tArrayStack.pop(); + if (! m_tArrayStack.empty()) + { + m_pArray = m_tArrayStack.top(); + } } else if (sName == "true") { CCString *str = new CCString("1"); - if (m_bInArray) + if (SAX_ARRAY == curState) { m_pArray->addObject(str); } - else + else if (SAX_DICT == curState) { m_pCurDict->setObject(str, m_sCurKey); } @@ -170,11 +205,11 @@ public: else if (sName == "false") { CCString *str = new CCString("0"); - if (m_bInArray) + if (SAX_ARRAY == curState) { m_pArray->addObject(str); } - else + else if (SAX_DICT == curState) { m_pCurDict->setObject(str, m_sCurKey); } @@ -189,6 +224,8 @@ public: { return; } + + CCSAXState curState = m_tStateStack.empty() ? SAX_DICT : m_tStateStack.top(); CCString *pText = new CCString(); pText->m_sString = std::string((char*)ch,0,len); @@ -203,11 +240,11 @@ public: { CCAssert(!m_sCurKey.empty(), "not found key : "); - if (m_bInArray) + if (SAX_ARRAY == curState) { m_pArray->addObject(pText); } - else + else if (SAX_DICT == curState) { m_pCurDict->setObject(pText, m_sCurKey); } From 5d70774b4fa353b8b0db70d7bce09a075ff53965 Mon Sep 17 00:00:00 2001 From: natural-law Date: Tue, 14 Jun 2011 16:15:20 +0800 Subject: [PATCH 2/2] fixed #524, Parse the special format of plist files on ios & airplay. --- .../platform/airplay/CCFileUtils_airplay.cpp | 347 ++++++++++-------- cocos2dx/platform/ios/CCFileUtils_ios.mm | 26 ++ 2 files changed, 215 insertions(+), 158 deletions(-) diff --git a/cocos2dx/platform/airplay/CCFileUtils_airplay.cpp b/cocos2dx/platform/airplay/CCFileUtils_airplay.cpp index 81e3aa9c1f..c41951eea4 100644 --- a/cocos2dx/platform/airplay/CCFileUtils_airplay.cpp +++ b/cocos2dx/platform/airplay/CCFileUtils_airplay.cpp @@ -36,195 +36,226 @@ NS_CC_BEGIN; typedef enum { - SAX_NONE = 0, - SAX_KEY, - SAX_DICT, - SAX_INT, - SAX_REAL, - SAX_STRING + SAX_NONE = 0, + SAX_KEY, + SAX_DICT, + SAX_INT, + SAX_REAL, + SAX_STRING, + SAX_ARRAY }CCSAXState; - class CCDictMaker : public CCSAXDelegator { public: - CCDictionary *m_pRootDict; - CCDictionary *m_pCurDict; - std::stack*> m_tDictStack; - std::string m_sCurKey;///< parsed key - CCSAXState m_tState; - bool m_bInArray; + CCDictionary *m_pRootDict; + CCDictionary *m_pCurDict; + std::stack*> m_tDictStack; + std::string m_sCurKey;///< parsed key + CCSAXState m_tState; CCMutableArray *m_pArray; + std::stack*> m_tArrayStack; + std::stack m_tStateStack; + public: - CCDictMaker() - { + CCDictMaker() + { m_pRootDict = NULL; m_pCurDict = NULL; m_tState = SAX_NONE; - m_pArray = NULL; - m_bInArray = false; - } - ~CCDictMaker() - { + } - } - CCDictionary *getDict() - { - return m_pRootDict; - } - CCDictionary *dictionaryWithContentsOfFile(const char *pFileName) - { - CCSAXParser parser; - parser.init(NULL); - parser.setDelegator(this); - parser.parse(pFileName); - return m_pRootDict; - } + ~CCDictMaker() + { + } -void startElement(void *ctx, const XML_Char *name, const XML_Char **atts) -{ - std::string sName((char*)name); - if( sName == "dict" ) - { - CCDictionary *pNewDict = new CCDictionary(); - if(! m_pRootDict) - { - m_pRootDict = pNewDict; - pNewDict->autorelease(); - } - else - { - CCAssert(m_pCurDict && !m_sCurKey.empty(), ""); - m_pCurDict->setObject(pNewDict, m_sCurKey); - pNewDict->release(); - m_sCurKey.clear(); - } - m_pCurDict = pNewDict; - m_tDictStack.push(m_pCurDict); - m_tState = SAX_DICT; - } - else if(sName == "key") - { - m_tState = SAX_KEY; - } - else if(sName == "integer") - { - m_tState = SAX_INT; - } - else if(sName == "real") - { - m_tState = SAX_REAL; - } - else if(sName == "string") - { - m_tState = SAX_STRING; - } - else - { - if (sName == "array") + CCDictionary *dictionaryWithContentsOfFile(const char *pFileName) + { + CCSAXParser parser; + + if (false == parser.init("UTF-8")) { - m_bInArray = true; + return NULL; + } + parser.setDelegator(this); + + parser.parse(pFileName); + return m_pRootDict; + } + + void startElement(void *ctx, const char *name, const char **atts) + { + CC_UNUSED_PARAM(ctx); + CC_UNUSED_PARAM(atts); + std::string sName((char*)name); + if( sName == "dict" ) + { + m_pCurDict = new CCDictionary(); + if(! m_pRootDict) + { + m_pRootDict = m_pCurDict; + } + m_tState = SAX_DICT; + + CCSAXState preState = SAX_NONE; + if (! m_tStateStack.empty()) + { + preState = m_tStateStack.top(); + } + + if (SAX_ARRAY == preState) + { + // add the dictionary into the array + m_pArray->addObject(m_pCurDict); + } + else if (SAX_DICT == preState) + { + // add the dictionary into the pre dictionary + CCAssert(! m_tDictStack.empty(), "The state is wrong!"); + CCDictionary* pPreDict = m_tDictStack.top(); + pPreDict->setObject(m_pCurDict, m_sCurKey); + } + m_pCurDict->autorelease(); + + // record the dict state + m_tStateStack.push(m_tState); + m_tDictStack.push(m_pCurDict); + } + else if(sName == "key") + { + m_tState = SAX_KEY; + } + else if(sName == "integer") + { + m_tState = SAX_INT; + } + else if(sName == "real") + { + m_tState = SAX_REAL; + } + else if(sName == "string") + { + m_tState = SAX_STRING; + } + else if (sName == "array") + { + m_tState = SAX_ARRAY; m_pArray = new CCMutableArray(); - } - m_tState = SAX_NONE; - } -} -void endElement(void *ctx, const XML_Char *name) -{ - std::string sName((char*)name); - if( sName == "dict" ) - { - m_tDictStack.pop(); - if ( !m_tDictStack.empty() ) - { - m_pCurDict = (CCDictionary*)(m_tDictStack.top()); - } - } - else if (sName == "array") - { - CCAssert(m_bInArray, "The plist file is wrong!"); - m_pCurDict->setObject(m_pArray, m_sCurKey); - m_pArray->release(); - m_pArray = NULL; - m_bInArray = false; - } - else if (sName == "true") - { - CCString *str = new CCString("1"); - if (m_bInArray) - { - m_pArray->addObject(str); + + CCSAXState preState = m_tStateStack.empty() ? SAX_DICT : m_tStateStack.top(); + if (preState == SAX_DICT) + { + m_pCurDict->setObject(m_pArray, m_sCurKey); + } + else if (preState == SAX_ARRAY) + { + CCAssert(! m_tArrayStack.empty(), "The state is worng!"); + CCMutableArray* pPreArray = m_tArrayStack.top(); + pPreArray->addObject(m_pArray); + } + m_pArray->release(); + // record the array state + m_tStateStack.push(m_tState); + m_tArrayStack.push(m_pArray); } else { - m_pCurDict->setObject(str, m_sCurKey); + m_tState = SAX_NONE; } - str->release(); } - else if (sName == "false") + + void endElement(void *ctx, const char *name) { - CCString *str = new CCString("0"); - if (m_bInArray) + CC_UNUSED_PARAM(ctx); + CCSAXState curState = m_tStateStack.empty() ? SAX_DICT : m_tStateStack.top(); + std::string sName((char*)name); + if( sName == "dict" ) { - m_pArray->addObject(str); + m_tStateStack.pop(); + m_tDictStack.pop(); + if ( !m_tDictStack.empty()) + { + m_pCurDict = m_tDictStack.top(); + } } - else + else if (sName == "array") { - m_pCurDict->setObject(str, m_sCurKey); + m_tStateStack.pop(); + m_tArrayStack.pop(); + if (! m_tArrayStack.empty()) + { + m_pArray = m_tArrayStack.top(); + } } - str->release(); + else if (sName == "true") + { + CCString *str = new CCString("1"); + if (SAX_ARRAY == curState) + { + m_pArray->addObject(str); + } + else if (SAX_DICT == curState) + { + m_pCurDict->setObject(str, m_sCurKey); + } + str->release(); + } + else if (sName == "false") + { + CCString *str = new CCString("0"); + if (SAX_ARRAY == curState) + { + m_pArray->addObject(str); + } + else if (SAX_DICT == curState) + { + m_pCurDict->setObject(str, m_sCurKey); + } + str->release(); + } + m_tState = SAX_NONE; } - m_tState = SAX_NONE; -} -void textHandler(void *ctx, const XML_Char *ch, int len) -{ - if (m_tState == SAX_NONE) - { - return; - } - CCString *pText = new CCString(); - pText->m_sString = std::string((char*)ch,0,len); + void textHandler(void *ctx, const char *ch, int len) + { + CC_UNUSED_PARAM(ctx); + if (m_tState == SAX_NONE) + { + return; + } - switch(m_tState) - { - case SAX_KEY: - { - m_sCurKey = pText->m_sString; - } - break; - case SAX_INT: - case SAX_REAL: - { - CCAssert(!m_sCurKey.empty(), "not found real : "); - if (m_bInArray) + CCSAXState curState = m_tStateStack.empty() ? SAX_DICT : m_tStateStack.top(); + CCString *pText = new CCString(); + pText->m_sString = std::string((char*)ch,0,len); + + switch(m_tState) + { + case SAX_KEY: + m_sCurKey = pText->m_sString; + break; + case SAX_INT: + case SAX_REAL: + case SAX_STRING: { - m_pArray->addObject(pText); + CCAssert(!m_sCurKey.empty(), "not found key : "); + + if (SAX_ARRAY == curState) + { + m_pArray->addObject(pText); + } + else if (SAX_DICT == curState) + { + m_pCurDict->setObject(pText, m_sCurKey); + } + break; } - else - { - m_pCurDict->setObject(pText, m_sCurKey); - } - break; - } - case SAX_STRING: - { - CCAssert(!m_sCurKey.empty(), "not found string"); - if (m_bInArray) - { - m_pArray->addObject(pText); - } - else - { - m_pCurDict->setObject(pText, m_sCurKey); - } - break; - } - } - pText->release(); -} + default: + break; + } + pText->release(); + } }; diff --git a/cocos2dx/platform/ios/CCFileUtils_ios.mm b/cocos2dx/platform/ios/CCFileUtils_ios.mm index ea761da73f..bb2165695d 100644 --- a/cocos2dx/platform/ios/CCFileUtils_ios.mm +++ b/cocos2dx/platform/ios/CCFileUtils_ios.mm @@ -37,6 +37,9 @@ THE SOFTWARE. using namespace cocos2d; +static void static_addValueToCCDict(id key, id value, CCDictionary* pDict); +static void static_addItemToCCArray(id item, CCMutableArray *pArray); + static const char *static_ccRemoveHDSuffixFromFile( const char *pszPath) { #if CC_IS_RETINA_DISPLAY_SUPPORTED @@ -157,6 +160,29 @@ static void static_addItemToCCArray(id item, CCMutableArray *pArray) pValue->release(); return; } + + // add dictionary value into array + if ([item isKindOfClass:[NSDictionary class]]) { + CCDictionary* pDictItem = new CCDictionary(); + for (id subKey in [item allKeys]) { + id subValue = [item objectForKey:subKey]; + static_addValueToCCDict(subKey, subValue, pDictItem); + } + pArray->addObject(pDictItem); + pDictItem->release(); + return; + } + + // add array value into array + if ([item isKindOfClass:[NSArray class]]) { + CCMutableArray *pArrayItem = new CCMutableArray(); + for (id subItem in item) { + static_addItemToCCArray(subItem, pArrayItem); + } + pArray->addObject(pArrayItem); + pArrayItem->release(); + return; + } } static void static_addValueToCCDict(id key, id value, CCDictionary* pDict)