From 591566b43afc254c4a4e6f96bcc08f84ad0e6962 Mon Sep 17 00:00:00 2001 From: James Chen Date: Tue, 19 Jun 2012 16:31:26 +0800 Subject: [PATCH] fixed #1335: Memory leaks in cocos2dx and CCBReader. --- .../CCBReader/CCBMemberVariableAssigner.h | 17 +- cocos2dx/extensions/CCBReader/CCBReader.cpp | 3 +- .../extensions/CCBReader/CCNodeLoader.cpp | 2 +- .../CCBReader/CCNodeLoaderLibrary.cpp | 1 + cocos2dx/label_nodes/CCLabelBMFont.cpp | 19 +- cocos2dx/platform/CCFileUtils.h | 4 +- cocos2dx/platform/CCImageCommon_cpp.h | 28 +- cocos2dx/platform/CCSAXParser.cpp | 13 +- cocos2dx/platform/ios/CCFileUtils.mm | 3 +- cocos2dx/platform/ios/CCImage.mm | 38 +- cocos2dx/platform/win32/CCFileUtils.cpp | 7 +- cocos2dx/support/image_support/TGAlib.cpp | 6 +- cocos2dx/support/zip_support/ZipUtils.cpp | 443 +++++++++--------- cocos2dx/textures/CCTextureCache.cpp | 15 +- cocos2dx/textures/CCTexturePVR.cpp | 4 +- .../ButtonTest/ButtonTestLayer.cpp | 9 + .../ButtonTest/ButtonTestLayer.h | 19 +- .../HelloCocosBuilderLayer.cpp | 11 + .../HelloCocosBuilderLayer.h | 3 + .../MenuTest/MenuTestLayer.cpp | 8 + .../CocosBuilderTest/MenuTest/MenuTestLayer.h | 3 + 21 files changed, 362 insertions(+), 294 deletions(-) diff --git a/cocos2dx/extensions/CCBReader/CCBMemberVariableAssigner.h b/cocos2dx/extensions/CCBReader/CCBMemberVariableAssigner.h index 3a0cb73812..eda0f81e23 100644 --- a/cocos2dx/extensions/CCBReader/CCBMemberVariableAssigner.h +++ b/cocos2dx/extensions/CCBReader/CCBMemberVariableAssigner.h @@ -5,12 +5,17 @@ NS_CC_EXT_BEGIN -#define CCB_MEMBERVARIABLEASSIGNER_GLUE(TARGET, MEMBERVARIABLENAME, MEMBERVARIABLETYPE, MEMBERVARIABLE) if(pTarget == TARGET && pMemberVariableName->compare(MEMBERVARIABLENAME) == 0) { \ - MEMBERVARIABLE = dynamic_cast(pNode); \ - CC_ASSERT(MEMBERVARIABLE); \ - MEMBERVARIABLE->retain(); \ - return true; \ -} +#define CCB_MEMBERVARIABLEASSIGNER_GLUE(TARGET, MEMBERVARIABLENAME, MEMBERVARIABLETYPE, MEMBERVARIABLE) \ + if (pTarget == TARGET && pMemberVariableName->compare(MEMBERVARIABLENAME) == 0) { \ + MEMBERVARIABLETYPE pOldVar = MEMBERVARIABLE; \ + MEMBERVARIABLE = dynamic_cast(pNode); \ + CC_ASSERT(MEMBERVARIABLE); \ + if (pOldVar != MEMBERVARIABLE) { \ + CC_SAFE_RELEASE(pOldVar); \ + MEMBERVARIABLE->retain(); \ + } \ + return true; \ + } class CC_DLL CCBMemberVariableAssigner { public: diff --git a/cocos2dx/extensions/CCBReader/CCBReader.cpp b/cocos2dx/extensions/CCBReader/CCBReader.cpp index a205dab924..822406653f 100644 --- a/cocos2dx/extensions/CCBReader/CCBReader.cpp +++ b/cocos2dx/extensions/CCBReader/CCBReader.cpp @@ -359,7 +359,8 @@ bool CCBReader::isSpriteSheetLoaded(CCString * pSpriteSheet) { } void CCBReader::addLoadedSpriteSheet(CCString * pSpriteSheet) { - pSpriteSheet->retain(); + // Since std::set will copy the string from pSpriteSheet, we needn't to retain 'pSpriteSheet'. + // pSpriteSheet->retain(); this->mLoadedSpriteSheets.insert(pSpriteSheet->m_sString); } diff --git a/cocos2dx/extensions/CCBReader/CCNodeLoader.cpp b/cocos2dx/extensions/CCBReader/CCNodeLoader.cpp index e658508c31..5ebc34972b 100644 --- a/cocos2dx/extensions/CCBReader/CCNodeLoader.cpp +++ b/cocos2dx/extensions/CCBReader/CCNodeLoader.cpp @@ -414,7 +414,7 @@ CCSpriteFrame * CCNodeLoader::parsePropTypeSpriteFrame(CCNode * pNode, CCNode * CCString * spriteFilePath = CCBReader::concat(pCCBReader->getCCBRootPath(), spriteFile); CCTexture2D * texture = CCTextureCache::sharedTextureCache()->addImage(spriteFilePath->getCString()); - CCRect bounds = CCRect::CCRect(0, 0, texture->getContentSize().width, texture->getContentSize().height); + CCRect bounds = CCRectMake(0, 0, texture->getContentSize().width, texture->getContentSize().height); spriteFrame = CCSpriteFrame::frameWithTexture(texture, bounds); } else { CCSpriteFrameCache * frameCache = CCSpriteFrameCache::sharedSpriteFrameCache(); diff --git a/cocos2dx/extensions/CCBReader/CCNodeLoaderLibrary.cpp b/cocos2dx/extensions/CCBReader/CCNodeLoaderLibrary.cpp index 1d1b2bca93..ff25b171ac 100644 --- a/cocos2dx/extensions/CCBReader/CCNodeLoaderLibrary.cpp +++ b/cocos2dx/extensions/CCBReader/CCNodeLoaderLibrary.cpp @@ -73,6 +73,7 @@ CCNodeLoader * CCNodeLoaderLibrary::getCCNodeLoader(CCString * pClassName) { void CCNodeLoaderLibrary::purge(bool pReleaseCCNodeLoaders) { if(pReleaseCCNodeLoaders) { for(CCNodeLoaderMap::iterator it = this->mCCNodeLoaders.begin(); it != this->mCCNodeLoaders.end(); it++) { + it->first->release(); it->second->release(); } } diff --git a/cocos2dx/label_nodes/CCLabelBMFont.cpp b/cocos2dx/label_nodes/CCLabelBMFont.cpp index 8167357579..de86c8afaf 100644 --- a/cocos2dx/label_nodes/CCLabelBMFont.cpp +++ b/cocos2dx/label_nodes/CCLabelBMFont.cpp @@ -359,23 +359,24 @@ static std::vector cc_utf16_vec_from_utf16_str(const unsigned sh // //FNTConfig Cache - free functions // -CCDictionary *configurations = NULL; +static CCDictionary* s_pConfigurations = NULL; + CCBMFontConfiguration* FNTConfigLoadFile( const char *fntFile) { CCBMFontConfiguration* pRet = NULL; - if( configurations == NULL ) + if( s_pConfigurations == NULL ) { - configurations = new CCDictionary(); + s_pConfigurations = new CCDictionary(); } - pRet = (CCBMFontConfiguration*)configurations->objectForKey(fntFile); + pRet = (CCBMFontConfiguration*)s_pConfigurations->objectForKey(fntFile); if( pRet == NULL ) { pRet = CCBMFontConfiguration::create(fntFile); if (pRet) { - configurations->setObject(pRet, fntFile); + s_pConfigurations->setObject(pRet, fntFile); } } @@ -384,10 +385,10 @@ CCBMFontConfiguration* FNTConfigLoadFile( const char *fntFile) void FNTConfigRemoveCache( void ) { - if (configurations) + if (s_pConfigurations) { - configurations->removeAllObjects(); - CC_SAFE_RELEASE_NULL(configurations); + s_pConfigurations->removeAllObjects(); + CC_SAFE_RELEASE_NULL(s_pConfigurations); } } @@ -1363,8 +1364,8 @@ void CCLabelBMFont::setFntFile(const char* fntFile) m_sFntFile = fntFile; - CC_SAFE_RELEASE(m_pConfiguration); CC_SAFE_RETAIN(newConf); + CC_SAFE_RELEASE(m_pConfiguration); m_pConfiguration = newConf; this->setTexture(CCTextureCache::sharedTextureCache()->addImage(m_pConfiguration->getAtlasName())); diff --git a/cocos2dx/platform/CCFileUtils.h b/cocos2dx/platform/CCFileUtils.h index 2b5221f696..0459244d08 100644 --- a/cocos2dx/platform/CCFileUtils.h +++ b/cocos2dx/platform/CCFileUtils.h @@ -44,7 +44,7 @@ public: @param[in] pszMode The read mode of the file @param[out] pSize If get the file data succeed the it will be the data size,or it will be 0 @return if success,the pointer of data will be returned,or NULL is returned - @warning If you get the file data succeed,you must delete it after used. + @warning If you get the file data succeed,you must delete[] it after used. */ unsigned char* getFileData(const char* pszFileName, const char* pszMode, unsigned long * pSize); @@ -53,7 +53,7 @@ public: @param[in] pszFileName The resource file name which contain the relative path of zip file @param[out] pSize If get the file data succeed the it will be the data size,or it will be 0 @return if success,the pointer of data will be returned,or NULL is returned - @warning If you get the file data succeed,you must delete it after used. + @warning If you get the file data succeed,you must delete[] it after used. */ unsigned char* getFileDataFromZip(const char* pszZipFilePath, const char* pszFileName, unsigned long * pSize); diff --git a/cocos2dx/platform/CCImageCommon_cpp.h b/cocos2dx/platform/CCImageCommon_cpp.h index cf0a451e36..4d65976e7f 100644 --- a/cocos2dx/platform/CCImageCommon_cpp.h +++ b/cocos2dx/platform/CCImageCommon_cpp.h @@ -94,22 +94,28 @@ CCImage::~CCImage() bool CCImage::initWithImageFile(const char * strPath, EImageFormat eImgFmt/* = eFmtPng*/) { - CC_UNUSED_PARAM(eImgFmt); - - unsigned long nSize; - unsigned char *pBuffer = CCFileUtils::sharedFileUtils()->getFileData(CCFileUtils::sharedFileUtils()->fullPathFromRelativePath(strPath), "rb", &nSize); - - return initWithImageData(pBuffer, nSize, eImgFmt); + bool bRet = false; + unsigned long nSize = 0; + unsigned char* pBuffer = CCFileUtils::sharedFileUtils()->getFileData(CCFileUtils::sharedFileUtils()->fullPathFromRelativePath(strPath), "rb", &nSize); + if (pBuffer != NULL && nSize > 0) + { + bRet = initWithImageData(pBuffer, nSize, eImgFmt); + } + CC_SAFE_DELETE_ARRAY(pBuffer); + return bRet; } bool CCImage::initWithImageFileThreadSafe(const char *fullpath, EImageFormat imageType) { - CC_UNUSED_PARAM(imageType); - - unsigned long nSize; + bool bRet = false; + unsigned long nSize = 0; unsigned char *pBuffer = CCFileUtils::sharedFileUtils()->getFileData(fullpath, "rb", &nSize); - - return initWithImageData(pBuffer, nSize, imageType); + if (pBuffer != NULL && nSize > 0) + { + bRet = initWithImageData(pBuffer, nSize, imageType); + } + CC_SAFE_DELETE_ARRAY(pBuffer); + return bRet; } bool CCImage::initWithImageData(void * pData, diff --git a/cocos2dx/platform/CCSAXParser.cpp b/cocos2dx/platform/CCSAXParser.cpp index a351d8099a..a1ee98ef5e 100644 --- a/cocos2dx/platform/CCSAXParser.cpp +++ b/cocos2dx/platform/CCSAXParser.cpp @@ -83,14 +83,15 @@ bool CCSAXParser::parse(const char* pXMLData, unsigned int uDataLength) bool CCSAXParser::parse(const char *pszFile) { - unsigned long size; - char *pBuffer = (char*)CCFileUtils::sharedFileUtils()->getFileData(pszFile, "rt", &size); - - if (!pBuffer) + bool bRet = false; + unsigned long size = 0; + char* pBuffer = (char*)CCFileUtils::sharedFileUtils()->getFileData(pszFile, "rt", &size); + if (pBuffer != NULL && size > 0) { - return false; + bRet = parse(pBuffer, size); } - return parse(pBuffer, size); + CC_SAFE_DELETE_ARRAY(pBuffer); + return bRet; } void CCSAXParser::startElement(void *ctx, const CC_XML_CHAR *name, const CC_XML_CHAR **atts) diff --git a/cocos2dx/platform/ios/CCFileUtils.mm b/cocos2dx/platform/ios/CCFileUtils.mm index 0ab53e89be..229212aa87 100644 --- a/cocos2dx/platform/ios/CCFileUtils.mm +++ b/cocos2dx/platform/ios/CCFileUtils.mm @@ -447,7 +447,8 @@ CCArray* ccFileUtils_arrayWithContentsOfFileThreadSafe(const char* pFileName) unsigned char* CCFileUtils::getFileData(const char* pszFileName, const char* pszMode, unsigned long * pSize) { unsigned char * pBuffer = NULL; - + CCAssert(pszFileName != NULL && pSize != NULL && pszMode != NULL, "Invaild parameters."); + *pSize = 0; do { // read the file from hardware diff --git a/cocos2dx/platform/ios/CCImage.mm b/cocos2dx/platform/ios/CCImage.mm index c46644dc2f..43932a9654 100644 --- a/cocos2dx/platform/ios/CCImage.mm +++ b/cocos2dx/platform/ios/CCImage.mm @@ -359,23 +359,35 @@ CCImage::~CCImage() bool CCImage::initWithImageFile(const char * strPath, EImageFormat eImgFmt/* = eFmtPng*/) { - unsigned long nSize; - CCFileUtils *fileUtils = CCFileUtils::sharedFileUtils(); - unsigned char *pBuffer = fileUtils->getFileData(fileUtils->fullPathFromRelativePath(strPath), "rb", &nSize); - - return initWithImageData(pBuffer, nSize, eImgFmt); + bool bRet = false; + unsigned long nSize = 0; + unsigned char* pBuffer = CCFileUtils::sharedFileUtils()->getFileData( + CCFileUtils::sharedFileUtils()->fullPathFromRelativePath(strPath), + "rb", + &nSize); + + if (pBuffer != NULL && nSize > 0) + { + bRet = initWithImageData(pBuffer, nSize, eImgFmt); + } + CC_SAFE_DELETE_ARRAY(pBuffer); + return bRet; } bool CCImage::initWithImageFileThreadSafe(const char *fullpath, EImageFormat imageType) { - CC_UNUSED_PARAM(imageType); - /* - * CCFileUtils::fullPathFromRelativePath() is not thread-safe, it use autorelease(). - */ - unsigned long nSize; - unsigned char *pBuffer = CCFileUtils::sharedFileUtils()->getFileData(fullpath, "rb", &nSize); - - return initWithImageData(pBuffer, nSize, imageType); + /* + * CCFileUtils::fullPathFromRelativePath() is not thread-safe, it use autorelease(). + */ + bool bRet = false; + unsigned long nSize = 0; + unsigned char* pBuffer = CCFileUtils::sharedFileUtils()->getFileData(fullpath, "rb", &nSize); + if (pBuffer != NULL && nSize > 0) + { + bRet = initWithImageData(pBuffer, nSize, imageType); + } + CC_SAFE_DELETE_ARRAY(pBuffer); + return bRet; } bool CCImage::initWithImageData(void * pData, diff --git a/cocos2dx/platform/win32/CCFileUtils.cpp b/cocos2dx/platform/win32/CCFileUtils.cpp index 87ee6ef4ed..f6ce0c42e2 100644 --- a/cocos2dx/platform/win32/CCFileUtils.cpp +++ b/cocos2dx/platform/win32/CCFileUtils.cpp @@ -190,10 +190,11 @@ const char *CCFileUtils::fullPathFromRelativeFile(const char *pszFilename, const return pRet->m_sString.c_str(); } -unsigned char* CCFileUtils::getFileData(const char* pszFileName, const char* pszMode, unsigned long * pSize) +unsigned char* CCFileUtils::getFileData(const char* pszFileName, const char* pszMode, unsigned long* pSize) { - unsigned char * pBuffer = NULL; - + unsigned char* pBuffer = NULL; + CCAssert(pszFileName != NULL && pSize != NULL && pszMode != NULL, "Invaild parameters."); + *pSize = 0; do { // read the file from hardware diff --git a/cocos2dx/support/image_support/TGAlib.cpp b/cocos2dx/support/image_support/TGAlib.cpp index 7f97cfafe0..5e81daca0f 100644 --- a/cocos2dx/support/image_support/TGAlib.cpp +++ b/cocos2dx/support/image_support/TGAlib.cpp @@ -198,8 +198,8 @@ tImageTGA * tgaLoad(const char *pszFilename) int mode,total; tImageTGA *info = NULL; - unsigned long nSize; - unsigned char *pBuffer = CCFileUtils::sharedFileUtils()->getFileData(pszFilename, "rb", &nSize); + unsigned long nSize = 0; + unsigned char* pBuffer = CCFileUtils::sharedFileUtils()->getFileData(pszFilename, "rb", &nSize); do { @@ -270,6 +270,8 @@ tImageTGA * tgaLoad(const char *pszFilename) } } while(0); + CC_SAFE_DELETE_ARRAY(pBuffer); + return info; } diff --git a/cocos2dx/support/zip_support/ZipUtils.cpp b/cocos2dx/support/zip_support/ZipUtils.cpp index ece5c179e5..199ba3db83 100644 --- a/cocos2dx/support/zip_support/ZipUtils.cpp +++ b/cocos2dx/support/zip_support/ZipUtils.cpp @@ -29,256 +29,255 @@ THE SOFTWARE. #include "ccMacros.h" #include "CCFileUtils.h" -namespace cocos2d +NS_CC_BEGIN + +// memory in iPhone is precious +// Should buffer factor be 1.5 instead of 2 ? +#define BUFFER_INC_FACTOR (2) + +int ZipUtils::ccInflateMemoryWithHint(unsigned char *in, unsigned int inLength, unsigned char **out, unsigned int *outLength, unsigned int outLenghtHint) { - // memory in iPhone is precious - // Should buffer factor be 1.5 instead of 2 ? - #define BUFFER_INC_FACTOR (2) + /* ret value */ + int err = Z_OK; - int ZipUtils::ccInflateMemoryWithHint(unsigned char *in, unsigned int inLength, unsigned char **out, unsigned int *outLength, unsigned int outLenghtHint) - { - /* ret value */ - int err = Z_OK; + int bufferSize = outLenghtHint; + *out = new unsigned char[bufferSize]; - int bufferSize = outLenghtHint; - *out = new unsigned char[bufferSize]; + z_stream d_stream; /* decompression stream */ + d_stream.zalloc = (alloc_func)0; + d_stream.zfree = (free_func)0; + d_stream.opaque = (voidpf)0; - z_stream d_stream; /* decompression stream */ - d_stream.zalloc = (alloc_func)0; - d_stream.zfree = (free_func)0; - d_stream.opaque = (voidpf)0; + d_stream.next_in = in; + d_stream.avail_in = inLength; + d_stream.next_out = *out; + d_stream.avail_out = bufferSize; - d_stream.next_in = in; - d_stream.avail_in = inLength; - d_stream.next_out = *out; - d_stream.avail_out = bufferSize; - - /* window size to hold 256k */ - if( (err = inflateInit2(&d_stream, 15 + 32)) != Z_OK ) - return err; - - for (;;) - { - err = inflate(&d_stream, Z_NO_FLUSH); - - if (err == Z_STREAM_END) - { - break; - } - - switch (err) - { - case Z_NEED_DICT: - err = Z_DATA_ERROR; - case Z_DATA_ERROR: - case Z_MEM_ERROR: - inflateEnd(&d_stream); - return err; - } - - // not enough memory ? - if (err != Z_STREAM_END) - { - delete [] *out; - *out = new unsigned char[bufferSize * BUFFER_INC_FACTOR]; - - /* not enough memory, ouch */ - if (! *out ) - { - CCLOG("cocos2d: ZipUtils: realloc failed"); - inflateEnd(&d_stream); - return Z_MEM_ERROR; - } - - d_stream.next_out = *out + bufferSize; - d_stream.avail_out = bufferSize; - bufferSize *= BUFFER_INC_FACTOR; - } - } - - *outLength = bufferSize - d_stream.avail_out; - err = inflateEnd(&d_stream); + /* window size to hold 256k */ + if( (err = inflateInit2(&d_stream, 15 + 32)) != Z_OK ) return err; - } - int ZipUtils::ccInflateMemoryWithHint(unsigned char *in, unsigned int inLength, unsigned char **out, unsigned int outLengthHint) + for (;;) { - unsigned int outLength = 0; - int err = ccInflateMemoryWithHint(in, inLength, out, &outLength, outLengthHint); + err = inflate(&d_stream, Z_NO_FLUSH); - if (err != Z_OK || *out == NULL) { - if (err == Z_MEM_ERROR) - { - CCLOG("cocos2d: ZipUtils: Out of memory while decompressing map data!"); - } else - if (err == Z_VERSION_ERROR) - { - CCLOG("cocos2d: ZipUtils: Incompatible zlib version!"); - } else - if (err == Z_DATA_ERROR) - { - CCLOG("cocos2d: ZipUtils: Incorrect zlib compressed data!"); - } - else - { - CCLOG("cocos2d: ZipUtils: Unknown error while decompressing map data!"); - } - - delete[] *out; - *out = NULL; - outLength = 0; + if (err == Z_STREAM_END) + { + break; } - return outLength; + switch (err) + { + case Z_NEED_DICT: + err = Z_DATA_ERROR; + case Z_DATA_ERROR: + case Z_MEM_ERROR: + inflateEnd(&d_stream); + return err; + } + + // not enough memory ? + if (err != Z_STREAM_END) + { + delete [] *out; + *out = new unsigned char[bufferSize * BUFFER_INC_FACTOR]; + + /* not enough memory, ouch */ + if (! *out ) + { + CCLOG("cocos2d: ZipUtils: realloc failed"); + inflateEnd(&d_stream); + return Z_MEM_ERROR; + } + + d_stream.next_out = *out + bufferSize; + d_stream.avail_out = bufferSize; + bufferSize *= BUFFER_INC_FACTOR; + } } - int ZipUtils::ccInflateMemory(unsigned char *in, unsigned int inLength, unsigned char **out) - { - // 256k for hint - return ccInflateMemoryWithHint(in, inLength, out, 256 * 1024); + *outLength = bufferSize - d_stream.avail_out; + err = inflateEnd(&d_stream); + return err; +} + +int ZipUtils::ccInflateMemoryWithHint(unsigned char *in, unsigned int inLength, unsigned char **out, unsigned int outLengthHint) +{ + unsigned int outLength = 0; + int err = ccInflateMemoryWithHint(in, inLength, out, &outLength, outLengthHint); + + if (err != Z_OK || *out == NULL) { + if (err == Z_MEM_ERROR) + { + CCLOG("cocos2d: ZipUtils: Out of memory while decompressing map data!"); + } else + if (err == Z_VERSION_ERROR) + { + CCLOG("cocos2d: ZipUtils: Incompatible zlib version!"); + } else + if (err == Z_DATA_ERROR) + { + CCLOG("cocos2d: ZipUtils: Incorrect zlib compressed data!"); + } + else + { + CCLOG("cocos2d: ZipUtils: Unknown error while decompressing map data!"); + } + + delete[] *out; + *out = NULL; + outLength = 0; } - int ZipUtils::ccInflateGZipFile(const char *path, unsigned char **out) + return outLength; +} + +int ZipUtils::ccInflateMemory(unsigned char *in, unsigned int inLength, unsigned char **out) +{ + // 256k for hint + return ccInflateMemoryWithHint(in, inLength, out, 256 * 1024); +} + +int ZipUtils::ccInflateGZipFile(const char *path, unsigned char **out) +{ + int len; + unsigned int offset = 0; + + CCAssert(out, ""); + CCAssert(&*out, ""); + + gzFile inFile = gzopen(path, "rb"); + if( inFile == NULL ) { + CCLOG("cocos2d: ZipUtils: error open gzip file: %s", path); + return -1; + } + + /* 512k initial decompress buffer */ + unsigned int bufferSize = 512 * 1024; + unsigned int totalBufferSize = bufferSize; + + *out = (unsigned char*)malloc( bufferSize ); + if( ! out ) { - int len; - unsigned int offset = 0; + CCLOG("cocos2d: ZipUtils: out of memory"); + return -1; + } - CCAssert(out, ""); - CCAssert(&*out, ""); - - gzFile inFile = gzopen(path, "rb"); - if( inFile == NULL ) { - CCLOG("cocos2d: ZipUtils: error open gzip file: %s", path); + for (;;) { + len = gzread(inFile, *out + offset, bufferSize); + if (len < 0) + { + CCLOG("cocos2d: ZipUtils: error in gzread"); + free( *out ); + *out = NULL; return -1; } + if (len == 0) + { + break; + } - /* 512k initial decompress buffer */ - unsigned int bufferSize = 512 * 1024; - unsigned int totalBufferSize = bufferSize; + offset += len; - *out = (unsigned char*)malloc( bufferSize ); - if( ! out ) + // finish reading the file + if( (unsigned int)len < bufferSize ) + { + break; + } + + bufferSize *= BUFFER_INC_FACTOR; + totalBufferSize += bufferSize; + unsigned char *tmp = (unsigned char*)realloc(*out, totalBufferSize ); + + if( ! tmp ) { CCLOG("cocos2d: ZipUtils: out of memory"); + free( *out ); + *out = NULL; return -1; } - for (;;) { - len = gzread(inFile, *out + offset, bufferSize); - if (len < 0) - { - CCLOG("cocos2d: ZipUtils: error in gzread"); - free( *out ); - *out = NULL; - return -1; - } - if (len == 0) - { - break; - } - - offset += len; - - // finish reading the file - if( (unsigned int)len < bufferSize ) - { - break; - } - - bufferSize *= BUFFER_INC_FACTOR; - totalBufferSize += bufferSize; - unsigned char *tmp = (unsigned char*)realloc(*out, totalBufferSize ); - - if( ! tmp ) - { - CCLOG("cocos2d: ZipUtils: out of memory"); - free( *out ); - *out = NULL; - return -1; - } - - *out = tmp; - } - - if (gzclose(inFile) != Z_OK) - { - CCLOG("cocos2d: ZipUtils: gzclose failed"); - } - - return offset; + *out = tmp; } - int ZipUtils::ccInflateCCZFile(const char *path, unsigned char **out) + if (gzclose(inFile) != Z_OK) { - CCAssert(out, ""); - CCAssert(&*out, ""); - - // load file into memory - unsigned char *compressed = NULL; - - int fileLen = 0; - compressed = CCFileUtils::sharedFileUtils()->getFileData(path, "rb", (unsigned long *)(&fileLen)); - // int fileLen = CCFileUtils::sharedFileUtils()->ccLoadFileIntoMemory( path, &compressed ); - - if( fileLen < 0 ) - { - CCLOG("cocos2d: Error loading CCZ compressed file"); - return -1; - } - - struct CCZHeader *header = (struct CCZHeader*) compressed; - - // verify header - if( header->sig[0] != 'C' || header->sig[1] != 'C' || header->sig[2] != 'Z' || header->sig[3] != '!' ) - { - CCLOG("cocos2d: Invalid CCZ file"); - delete [] compressed; - return -1; - } - - // verify header version - unsigned int version = CC_SWAP_INT16_BIG_TO_HOST( header->version ); - if( version > 2 ) - { - CCLOG("cocos2d: Unsupported CCZ header format"); - delete [] compressed; - return -1; - } - - // verify compression format - if( CC_SWAP_INT16_BIG_TO_HOST(header->compression_type) != CCZ_COMPRESSION_ZLIB ) - { - CCLOG("cocos2d: CCZ Unsupported compression method"); - delete [] compressed; - return -1; - } - - unsigned int len = CC_SWAP_INT32_BIG_TO_HOST( header->len ); - - *out = (unsigned char*)malloc( len ); - if(! *out ) - { - CCLOG("cocos2d: CCZ: Failed to allocate memory for texture"); - delete [] compressed; - return -1; - } - - - unsigned long destlen = len; - unsigned long source = (unsigned long) compressed + sizeof(*header); - int ret = uncompress(*out, &destlen, (Bytef*)source, fileLen - sizeof(*header) ); - - delete [] compressed; - - if( ret != Z_OK ) - { - CCLOG("cocos2d: CCZ: Failed to uncompress data"); - free( *out ); - *out = NULL; - return -1; - } - - return len; + CCLOG("cocos2d: ZipUtils: gzclose failed"); } -} // end of namespace cocos2d + return offset; +} + +int ZipUtils::ccInflateCCZFile(const char *path, unsigned char **out) +{ + CCAssert(out, ""); + CCAssert(&*out, ""); + + // load file into memory + unsigned char* compressed = NULL; + + unsigned long fileLen = 0; + compressed = CCFileUtils::sharedFileUtils()->getFileData(path, "rb", &fileLen); + + if(NULL == compressed || 0 == fileLen) + { + CCLOG("cocos2d: Error loading CCZ compressed file"); + return -1; + } + + struct CCZHeader *header = (struct CCZHeader*) compressed; + + // verify header + if( header->sig[0] != 'C' || header->sig[1] != 'C' || header->sig[2] != 'Z' || header->sig[3] != '!' ) + { + CCLOG("cocos2d: Invalid CCZ file"); + delete [] compressed; + return -1; + } + + // verify header version + unsigned int version = CC_SWAP_INT16_BIG_TO_HOST( header->version ); + if( version > 2 ) + { + CCLOG("cocos2d: Unsupported CCZ header format"); + delete [] compressed; + return -1; + } + + // verify compression format + if( CC_SWAP_INT16_BIG_TO_HOST(header->compression_type) != CCZ_COMPRESSION_ZLIB ) + { + CCLOG("cocos2d: CCZ Unsupported compression method"); + delete [] compressed; + return -1; + } + + unsigned int len = CC_SWAP_INT32_BIG_TO_HOST( header->len ); + + *out = (unsigned char*)malloc( len ); + if(! *out ) + { + CCLOG("cocos2d: CCZ: Failed to allocate memory for texture"); + delete [] compressed; + return -1; + } + + + unsigned long destlen = len; + unsigned long source = (unsigned long) compressed + sizeof(*header); + int ret = uncompress(*out, &destlen, (Bytef*)source, fileLen - sizeof(*header) ); + + delete [] compressed; + + if( ret != Z_OK ) + { + CCLOG("cocos2d: CCZ: Failed to uncompress data"); + free( *out ); + *out = NULL; + return -1; + } + + return len; +} + +NS_CC_END diff --git a/cocos2dx/textures/CCTextureCache.cpp b/cocos2dx/textures/CCTextureCache.cpp index 14ec6419ed..3cf920ada0 100644 --- a/cocos2dx/textures/CCTextureCache.cpp +++ b/cocos2dx/textures/CCTextureCache.cpp @@ -438,9 +438,10 @@ CCTexture2D * CCTextureCache::addImage(const char * path) } CCImage image; - unsigned long nSize; - unsigned char *pBuffer = CCFileUtils::sharedFileUtils()->getFileData(fullpath.c_str(), "rb", &nSize); + unsigned long nSize = 0; + unsigned char* pBuffer = CCFileUtils::sharedFileUtils()->getFileData(fullpath.c_str(), "rb", &nSize); CC_BREAK_IF(! image.initWithImageData((void*)pBuffer, nSize, eImageFormat)); + CC_SAFE_DELETE_ARRAY(pBuffer); texture = new CCTexture2D(); texture->initWithImage(&image, resolution); @@ -453,8 +454,7 @@ CCTexture2D * CCTextureCache::addImage(const char * path) #endif m_pTextures->setObject(texture, pathKey.c_str()); - // autorelease prevents possible crash in multithreaded environments - texture->autorelease(); + texture->release(); } else { @@ -854,9 +854,8 @@ void VolatileTexture::reloadAllTextures() } else { - unsigned long nSize; - unsigned char *pBuffer = CCFileUtils::sharedFileUtils()->getFileData(vt->m_strFileName.c_str(), "rb", &nSize); - + unsigned long nSize = 0; + unsigned char* pBuffer = CCFileUtils::sharedFileUtils()->getFileData(vt->m_strFileName.c_str(), "rb", &nSize); if (image.initWithImageData((void*)pBuffer, nSize, vt->m_FmtImage)) { @@ -865,6 +864,8 @@ void VolatileTexture::reloadAllTextures() vt->texture->initWithImage(&image); CCTexture2D::setDefaultAlphaPixelFormat(oldPixelFormat); } + + CC_SAFE_DELETE_ARRAY(pBuffer); } } break; diff --git a/cocos2dx/textures/CCTexturePVR.cpp b/cocos2dx/textures/CCTexturePVR.cpp index 0028e2b34f..ce9a6a5f7b 100755 --- a/cocos2dx/textures/CCTexturePVR.cpp +++ b/cocos2dx/textures/CCTexturePVR.cpp @@ -421,12 +421,12 @@ bool CCTexturePVR::initWithContentsOfFile(const char* path) if (!unpackPVRData(pvrdata, pvrlen) || !createGLTexture()) { - delete [] pvrdata; + CC_SAFE_DELETE_ARRAY(pvrdata); this->release(); return false; } - delete [] pvrdata; + CC_SAFE_DELETE_ARRAY(pvrdata); return true; } diff --git a/tests/tests/ExtensionsTest/CocosBuilderTest/ButtonTest/ButtonTestLayer.cpp b/tests/tests/ExtensionsTest/CocosBuilderTest/ButtonTest/ButtonTestLayer.cpp index 5ccf142ea6..6e5457b37e 100644 --- a/tests/tests/ExtensionsTest/CocosBuilderTest/ButtonTest/ButtonTestLayer.cpp +++ b/tests/tests/ExtensionsTest/CocosBuilderTest/ButtonTest/ButtonTestLayer.cpp @@ -5,6 +5,15 @@ USING_NS_CC; USING_NS_CC_EXT; +ButtonTestLayer::ButtonTestLayer() +: mCCControlEventLabel(NULL) +{} + +ButtonTestLayer::~ButtonTestLayer() +{ + CC_SAFE_RELEASE(mCCControlEventLabel); +} + SEL_MenuHandler ButtonTestLayer::onResolveCCBCCMenuItemSelector(CCObject * pTarget, CCString * pSelectorName) { return NULL; } diff --git a/tests/tests/ExtensionsTest/CocosBuilderTest/ButtonTest/ButtonTestLayer.h b/tests/tests/ExtensionsTest/CocosBuilderTest/ButtonTest/ButtonTestLayer.h index 34aa2c01c7..0234353a2a 100644 --- a/tests/tests/ExtensionsTest/CocosBuilderTest/ButtonTest/ButtonTestLayer.h +++ b/tests/tests/ExtensionsTest/CocosBuilderTest/ButtonTest/ButtonTestLayer.h @@ -11,17 +11,20 @@ class ButtonTestLayer , public cocos2d::extension::CCBMemberVariableAssigner , public cocos2d::extension::CCBSelectorResolver { - public: - CCB_STATIC_NEW_AUTORELEASE_OBJECT_WITH_INIT_METHOD(ButtonTestLayer, node); +public: + CCB_STATIC_NEW_AUTORELEASE_OBJECT_WITH_INIT_METHOD(ButtonTestLayer, node); - virtual cocos2d::SEL_MenuHandler onResolveCCBCCMenuItemSelector(cocos2d::CCObject * pTarget, cocos2d::CCString * pSelectorName); - virtual cocos2d::extension::SEL_CCControlHandler onResolveCCBCCControlSelector(cocos2d::CCObject * pTarget, cocos2d::CCString * pSelectorName); - virtual bool onAssignCCBMemberVariable(cocos2d::CCObject * pTarget, cocos2d::CCString * pMemberVariableName, cocos2d::CCNode * pNode); + ButtonTestLayer(); + virtual ~ButtonTestLayer(); - void onCCControlButtonClicked(cocos2d::CCObject * pSender, cocos2d::extension::CCControlEvent pCCControlEvent); + virtual cocos2d::SEL_MenuHandler onResolveCCBCCMenuItemSelector(cocos2d::CCObject * pTarget, cocos2d::CCString * pSelectorName); + virtual cocos2d::extension::SEL_CCControlHandler onResolveCCBCCControlSelector(cocos2d::CCObject * pTarget, cocos2d::CCString * pSelectorName); + virtual bool onAssignCCBMemberVariable(cocos2d::CCObject * pTarget, cocos2d::CCString * pMemberVariableName, cocos2d::CCNode * pNode); - private: - cocos2d::CCLabelBMFont * mCCControlEventLabel; + void onCCControlButtonClicked(cocos2d::CCObject * pSender, cocos2d::extension::CCControlEvent pCCControlEvent); + +private: + cocos2d::CCLabelBMFont * mCCControlEventLabel; }; #endif \ No newline at end of file diff --git a/tests/tests/ExtensionsTest/CocosBuilderTest/HelloCocosBuilder/HelloCocosBuilderLayer.cpp b/tests/tests/ExtensionsTest/CocosBuilderTest/HelloCocosBuilder/HelloCocosBuilderLayer.cpp index b26473bfa5..9c33fe7b97 100644 --- a/tests/tests/ExtensionsTest/CocosBuilderTest/HelloCocosBuilder/HelloCocosBuilderLayer.cpp +++ b/tests/tests/ExtensionsTest/CocosBuilderTest/HelloCocosBuilder/HelloCocosBuilderLayer.cpp @@ -14,6 +14,17 @@ USING_NS_CC; USING_NS_CC_EXT; +HelloCocosBuilderLayer::HelloCocosBuilderLayer() +: mBurstSprite(NULL) +, mTestTitleLabelTTF(NULL) +{} + +HelloCocosBuilderLayer::~HelloCocosBuilderLayer() +{ + CC_SAFE_RELEASE(mBurstSprite); + CC_SAFE_RELEASE(mTestTitleLabelTTF); +} + void HelloCocosBuilderLayer::openTest(const char * pCCBFileName, const char * pCCNodeName, CCNodeLoader * pCCNodeLoader) { /* Create an autorelease CCNodeLoaderLibrary. */ CCNodeLoaderLibrary * ccNodeLoaderLibrary = CCNodeLoaderLibrary::newDefaultCCNodeLoaderLibrary(); diff --git a/tests/tests/ExtensionsTest/CocosBuilderTest/HelloCocosBuilder/HelloCocosBuilderLayer.h b/tests/tests/ExtensionsTest/CocosBuilderTest/HelloCocosBuilder/HelloCocosBuilderLayer.h index 1a3524b361..b5bc30e368 100644 --- a/tests/tests/ExtensionsTest/CocosBuilderTest/HelloCocosBuilder/HelloCocosBuilderLayer.h +++ b/tests/tests/ExtensionsTest/CocosBuilderTest/HelloCocosBuilder/HelloCocosBuilderLayer.h @@ -26,6 +26,9 @@ class HelloCocosBuilderLayer public: CCB_STATIC_NEW_AUTORELEASE_OBJECT_WITH_INIT_METHOD(HelloCocosBuilderLayer, node); + HelloCocosBuilderLayer(); + virtual ~HelloCocosBuilderLayer(); + void openTest(const char * pCCBFileName, const char * pCCNodeName = NULL, cocos2d::extension::CCNodeLoader * pCCNodeLoader = NULL); virtual cocos2d::SEL_MenuHandler onResolveCCBCCMenuItemSelector(cocos2d::CCObject * pTarget, cocos2d::CCString * pSelectorName); diff --git a/tests/tests/ExtensionsTest/CocosBuilderTest/MenuTest/MenuTestLayer.cpp b/tests/tests/ExtensionsTest/CocosBuilderTest/MenuTest/MenuTestLayer.cpp index 9204ea6044..75ed49390c 100644 --- a/tests/tests/ExtensionsTest/CocosBuilderTest/MenuTest/MenuTestLayer.cpp +++ b/tests/tests/ExtensionsTest/CocosBuilderTest/MenuTest/MenuTestLayer.cpp @@ -5,6 +5,14 @@ USING_NS_CC; USING_NS_CC_EXT; +MenuTestLayer::MenuTestLayer() +: mMenuItemStatusLabelBMFont(NULL) +{} + +MenuTestLayer::~MenuTestLayer() +{ + CC_SAFE_RELEASE(mMenuItemStatusLabelBMFont); +} SEL_MenuHandler MenuTestLayer::onResolveCCBCCMenuItemSelector(CCObject * pTarget, CCString * pSelectorName) { CCB_SELECTORRESOLVER_CCMENUITEM_GLUE(this, "onMenuItemAClicked", MenuTestLayer::onMenuItemAClicked); diff --git a/tests/tests/ExtensionsTest/CocosBuilderTest/MenuTest/MenuTestLayer.h b/tests/tests/ExtensionsTest/CocosBuilderTest/MenuTest/MenuTestLayer.h index c4cd5e30eb..160fedd979 100644 --- a/tests/tests/ExtensionsTest/CocosBuilderTest/MenuTest/MenuTestLayer.h +++ b/tests/tests/ExtensionsTest/CocosBuilderTest/MenuTest/MenuTestLayer.h @@ -14,6 +14,9 @@ class MenuTestLayer public: CCB_STATIC_NEW_AUTORELEASE_OBJECT_WITH_INIT_METHOD(MenuTestLayer, node); + MenuTestLayer(); + virtual ~MenuTestLayer(); + virtual cocos2d::SEL_MenuHandler onResolveCCBCCMenuItemSelector(cocos2d::CCObject * pTarget, cocos2d::CCString * pSelectorName); virtual cocos2d::extension::SEL_CCControlHandler onResolveCCBCCControlSelector(cocos2d::CCObject * pTarget, cocos2d::CCString * pSelectorName); virtual bool onAssignCCBMemberVariable(cocos2d::CCObject * pTarget, cocos2d::CCString * pMemberVariableName, cocos2d::CCNode * pNode);