unsigned char* FileUtils::getFileData(const char* pszFileName, const char* pszMode, unsigned long * pSize)
{
    unsigned char * pBuffer = NULL;

    do 
    {
        if (strlen(s_ZipFilePath) != 0)
        {
            // if specify the zip file,load from it first
            pBuffer = getFileDataFromZip(s_ZipFilePath, pszFileName, pSize);
            BREAK_IF(pBuffer);
        }
        
        // read the file from hardware
        char fullPath[EOS_FILE_MAX_PATH] = {0};
        fullPathFromRelativePath(pszFileName, fullPath);

        BREAK_IF(strlen(fullPath) <= 0);
        FILE *fp = fopen(fullPath, pszMode);
        BREAK_IF(!fp);

        fseek(fp,0,SEEK_END);
        *pSize = ftell(fp);
        fseek(fp,0,SEEK_SET);
        pBuffer = new unsigned char[*pSize];
        fread(pBuffer,sizeof(unsigned char), *pSize,fp);
        fclose(fp);
    } while (0);

    return pBuffer;
}
unsigned char* CCFileUtils::getFileData(const char* pszFileName, const char* pszMode, unsigned long * pSize)
{	
	unsigned char * buffer = NULL;

	std::string full_path = pszFileName;

	// If it is not inside resource path
	if (full_path.find(s_strResourcePath) == std::string::npos) 
    {
			full_path = s_strResourcePath + pszFileName;
	}

	// if specify the zip file,load from it first
	if (s_pszZipFilePath[0] != 0)
	{
		buffer = getFileDataFromZip(s_pszZipFilePath.c_str(), full_path.c_str(), pSize);
	}

	// if that failed then let's try and load the file ourselves
	if (!buffer)
	{
		// read the file from hardware
		FILE *fp = fopen(full_path.c_str(), pszMode);
		if (fp)
		{
			fseek(fp, 0, SEEK_END);
			*pSize = ftell(fp);
			fseek(fp, 0, SEEK_SET);
			buffer = new unsigned char[*pSize];
			*pSize = fread(buffer, sizeof(unsigned char), *pSize, fp);
			fclose(fp);
		}
	}

	// we couldn't find the file
	if (!buffer && getIsPopupNotify())
	{
		std::string title = "Notification";
		std::string msg = "Get data from file(";
		msg.append(full_path);
		if (s_pszZipFilePath[0] != 0)
		{
			msg.append(") in zip archive(").append(s_pszZipFilePath);
		}
		msg.append(") failed!");

		CCMessageBox(msg.c_str(), title.c_str());
	}

	return buffer;
}
// 导出DragonBones的纹理图片(sheet.pvr)
void DotaAnimParser::exportDBTexturePic(const std::string &savePath, 
										const std::string &fcaFile)
{
	ssize_t size = 0;
	unsigned char * data = getFileDataFromZip(fcaFile.c_str(), "sheet.pvr", &size);
	if (data != nullptr && size > 0)
	{
		std::string fileName = savePath + "/sheet.pvr";
		FILE* fp = fopen(fileName.c_str(), "wb");
		if (fp)
		{
			fwrite(data, size, 1, fp);
			fclose(fp);
		}		
	}

	if (data != nullptr)
		free(data);
}
// 解析出DB纹理集数据
TextureAtlasData* DotaAnimParser::parseTextureAtlasData(
	const std::string &fcaFile, float scale/* = 1.f*/)
{
	ssize_t size = 0;
	char* data = (char *)getFileDataFromZip(fcaFile.c_str(), "plist", &size);
	if (nullptr == data || size <= 0)
	{
		free(data);
		return nullptr;
	}

	TextureAtlasData *textureAtlasData = new TextureAtlasData();
	textureAtlasData->name = "";
	textureAtlasData->imagePath = "sheet.pvr";

	cocos2d::ValueMap dict = cocos2d::FileUtils::getInstance()->getValueMapFromData(data, size);
	free(data);

	cocos2d::ValueMap& framesDict = dict["frames"].asValueMap();
	int format = 0;

	if (dict.find("metadata") != dict.end())
	{
		cocos2d::ValueMap& metadataDict = dict["metadata"].asValueMap();
		format = metadataDict["format"].asInt();
	}

	for (auto iter = framesDict.begin(); iter != framesDict.end(); ++iter)
	{
		TextureData *textureData = new TextureData();
		textureData->name = iter->first;

		cocos2d::ValueMap& frameDict = iter->second.asValueMap();

		if(format == 0) 
		{
			float x = frameDict["x"].asFloat();
			float y = frameDict["y"].asFloat();
			float w = frameDict["width"].asFloat();
			float h = frameDict["height"].asFloat();
			float ox = frameDict["offsetX"].asFloat();
			float oy = frameDict["offsetY"].asFloat();
			int ow = frameDict["originalWidth"].asInt();
			int oh = frameDict["originalHeight"].asInt();
			// check ow/oh
			if(!ow || !oh)
			{
				//CCLOGWARN("cocos2d: WARNING: originalWidth/Height not found on the SpriteFrame. AnchorPoint won't work as expected. Regenrate the .plist");
			}
			// abs ow/oh
			ow = abs(ow);
			oh = abs(oh);

			textureData->rotated = false;
			textureData->region.x = x / scale;
			textureData->region.y = y / scale;
			textureData->region.width = w / scale;
			textureData->region.height = h / scale;
		} 
		else if(format == 1 || format == 2) 
		{
			cocos2d::Rect frame = cocos2d::RectFromString(frameDict["frame"].asString());
			bool rotated = false;

			// rotation
			if (format == 2)
			{
				rotated = frameDict["rotated"].asBool();
			}

			cocos2d::Vec2 offset = cocos2d::PointFromString(frameDict["offset"].asString());
			cocos2d::Size sourceSize = cocos2d::SizeFromString(frameDict["sourceSize"].asString());

			textureData->rotated = rotated;
			textureData->region.x = frame.origin.x / scale;
			textureData->region.y = frame.origin.y / scale;
			
			if (rotated)
			{
				textureData->region.width = frame.size.height / scale;
				textureData->region.height = frame.size.width / scale;
			}
			else
			{
				textureData->region.width = frame.size.width / scale;
				textureData->region.height = frame.size.height / scale;
			}
		} 
		else if (format == 3)
		{
			// get values
			cocos2d::Size spriteSize = cocos2d::SizeFromString(frameDict["spriteSize"].asString());
			cocos2d::Vec2 spriteOffset = cocos2d::PointFromString(frameDict["spriteOffset"].asString());
			cocos2d::Size spriteSourceSize = cocos2d::SizeFromString(frameDict["spriteSourceSize"].asString());
			cocos2d::Rect textureRect = cocos2d::RectFromString(frameDict["textureRect"].asString());
			bool textureRotated = frameDict["textureRotated"].asBool();

			textureData->rotated = textureRotated;
			textureData->region.x = textureRect.origin.x / scale;
			textureData->region.y = textureRect.origin.y / scale;
			if (textureRotated)
			{
				textureData->region.width = spriteSize.height / scale;
				textureData->region.height = spriteSize.width / scale;
			}
			else
			{
				textureData->region.width = spriteSize.width / scale;
				textureData->region.height = spriteSize.height / scale;
			}
		}

		textureAtlasData->textureDataList.push_back(textureData);
	}

	return textureAtlasData;
}