Merge pull request #342 from rh101/vfs-support

Ensure FileStream is used for file access where possible
This commit is contained in:
HALX99 2021-04-25 18:55:10 -07:00 committed by GitHub
commit 5664291631
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 353 additions and 75 deletions

View File

@ -183,7 +183,8 @@ bool FontFreeType::createFontObject(const std::string &fontName, float fontSize)
std::unique_ptr<FT_StreamRec> fts(new FT_StreamRec()); std::unique_ptr<FT_StreamRec> fts(new FT_StreamRec());
fts->read = ft_stream_read_callback; fts->read = ft_stream_read_callback;
fts->close = ft_stream_close_callback; fts->close = ft_stream_close_callback;
fts->size = fs->seek(0, SEEK_END); fs->seek(0, SEEK_END);
fts->size = fs->tell();
fs->seek(0, SEEK_SET); fs->seek(0, SEEK_SET);
fts->descriptor.pointer = fs; fts->descriptor.pointer = fs;

View File

@ -68,7 +68,7 @@ protected:
AudioDecoderOgg(); AudioDecoderOgg();
~AudioDecoderOgg(); ~AudioDecoderOgg();
FileStream* _fileStream; FileStream* _fileStream = nullptr;
OggVorbis_File _vf; OggVorbis_File _vf;
friend class AudioDecoderManager; friend class AudioDecoderManager;

View File

@ -61,7 +61,7 @@ namespace cocos2d {
static int minimp3_seek_r(uint64_t position, void* user_data) static int minimp3_seek_r(uint64_t position, void* user_data)
{ {
return ((FileStream*)user_data)->seek(position, SEEK_SET) >= 0 ? 0 : -1; return ((FileStream*)user_data)->seek(position, SEEK_SET) < 0 ? -1 : 0;
} }
#else #else
static bool __mp3Inited = false; static bool __mp3Inited = false;

View File

@ -44,8 +44,7 @@ namespace cocos2d {
static int ov_fseek_r(void * handle, ogg_int64_t offset, int whence) static int ov_fseek_r(void * handle, ogg_int64_t offset, int whence)
{ {
auto n = ((FileStream*)handle)->seek(offset, whence); return ((FileStream*)handle)->seek(offset, whence) < 0 ? -1 : 0;
return n >= 0 ? 0 : -1;
} }
static long ov_ftell_r(void * handle) static long ov_ftell_r(void * handle)

View File

@ -141,7 +141,7 @@ namespace cocos2d {
ALOGW("The wav format %d doesn't supported currently!", (int)fmtInfo.AudioFormat); ALOGW("The wav format %d doesn't supported currently!", (int)fmtInfo.AudioFormat);
fileStream->close(); fileStream->close();
assert(false); assert(false);
return false;; return false;
} }
return wav_scan_chunk(wavf, WAV_DATA_ID, &h->PcmData, nullptr, 0); return wav_scan_chunk(wavf, WAV_DATA_ID, &h->PcmData, nullptr, 0);
@ -154,7 +154,8 @@ namespace cocos2d {
static int wav_seek(WAV_FILE* wavf, int offset) static int wav_seek(WAV_FILE* wavf, int offset)
{ {
auto newOffset = wavf->Stream->seek(wavf->PcmDataOffset + offset, SEEK_SET); wavf->Stream->seek(wavf->PcmDataOffset + offset, SEEK_SET);
const auto newOffset = wavf->Stream->tell();
return newOffset >= wavf->PcmDataOffset ? newOffset - wavf->PcmDataOffset : -1; return newOffset >= wavf->PcmDataOffset ? newOffset - wavf->PcmDataOffset : -1;
} }

View File

@ -1491,8 +1491,8 @@ void Console::commandUpload(int fd)
static std::string writablePath = FileUtils::getInstance()->getWritablePath(); static std::string writablePath = FileUtils::getInstance()->getWritablePath();
std::string filepath = writablePath + std::string(buf); std::string filepath = writablePath + std::string(buf);
FILE* fp = fopen(filepath.c_str(), "wb"); auto* fs = FileUtils::getInstance()->openFileStream(filepath, FileStream::Mode::WRITE);
if(!fp) if(!fs)
{ {
const char err[] = "can't create file!\n"; const char err[] = "can't create file!\n";
Console::Utility::sendToConsole(fd, err, strlen(err)); Console::Utility::sendToConsole(fd, err, strlen(err));
@ -1517,11 +1517,12 @@ void Console::commandUpload(int fd)
int dt = base64Decode(in, 4, &decode); int dt = base64Decode(in, 4, &decode);
if (dt > 0) if (dt > 0)
{ {
fwrite(decode, dt, 1, fp); fs->write(decode, dt);
} }
free(decode); free(decode);
} }
fclose(fp); fs->close();
delete fs;
} }
void Console::commandVersion(int fd, const std::string& /*args*/) void Console::commandVersion(int fd, const std::string& /*args*/)

View File

@ -154,7 +154,8 @@ public:
_checksumFileName = filename + ".chksum"; _checksumFileName = filename + ".chksum";
_fsMd5 = FileUtils::getInstance()->openFileStream(_checksumFileName, FileStream::Mode::WRITE); _fsMd5 = FileUtils::getInstance()->openFileStream(_checksumFileName, FileStream::Mode::WRITE);
if (_fsMd5->seek(0, SEEK_END) != sizeof(md5_state_s)) { _fsMd5->seek(0, SEEK_END);
if (_fsMd5->tell() != sizeof(md5_state_s)) {
md5_init(&_md5State); md5_init(&_md5State);
} else { } else {
_fsMd5->seek(0, SEEK_SET); _fsMd5->seek(0, SEEK_SET);
@ -819,10 +820,10 @@ void DownloaderCURL::_onDownloadFinished(TaskWrapper&& wrapper, int checkState)
if (checkState & kCheckSumStateSucceed) // No need download if (checkState & kCheckSumStateSucceed) // No need download
{ {
FileStream* fsOrigin = auto* fsOrigin = pFileUtils->openFileStream(coTask._fileName, FileStream::Mode::READ);
FileUtils::getInstance()->openFileStream(coTask._fileName, FileStream::Mode::READ);
if (fsOrigin) { if (fsOrigin) {
task.progressInfo.totalBytesExpected = fsOrigin->seek(0, SEEK_END); fsOrigin->seek(0, SEEK_END);
task.progressInfo.totalBytesExpected = fsOrigin->tell();
task.progressInfo.bytesReceived = task.progressInfo.totalBytesExpected; task.progressInfo.bytesReceived = task.progressInfo.totalBytesExpected;
task.progressInfo.totalBytesReceived = task.progressInfo.totalBytesExpected; task.progressInfo.totalBytesReceived = task.progressInfo.totalBytesExpected;
task.progressInfo.speedInBytes = task.progressInfo.totalBytesExpected; task.progressInfo.speedInBytes = task.progressInfo.totalBytesExpected;

View File

@ -409,7 +409,7 @@ void HttpClient::enableCookies(const char* cookieFile)
} }
else else
{ {
_cookieFilename = (FileUtils::getInstance()->getWritablePath() + "cookieFile.txt"); _cookieFilename = (FileUtils::getInstance()->getNativeWritableAbsolutePath() + "cookieFile.txt");
} }
} }

View File

@ -497,20 +497,17 @@ void FileUtils::writeDataToFile(Data data, const std::string& fullPath, std::fun
bool FileUtils::writeBinaryToFile(const void* data, size_t dataSize, const std::string& fullPath) bool FileUtils::writeBinaryToFile(const void* data, size_t dataSize, const std::string& fullPath)
{ {
const char* mode = "wb";
CCASSERT(!fullPath.empty() && dataSize > 0, "Invalid parameters."); CCASSERT(!fullPath.empty() && dataSize > 0, "Invalid parameters.");
auto fileutils = FileUtils::getInstance(); auto* fileUtils = FileUtils::getInstance();
do do
{ {
auto* fileStream = fileUtils->openFileStream(fullPath, FileStream::Mode::WRITE);
// Read the file from hardware // Read the file from hardware
FILE* fp = fopen(fullPath.c_str(), mode); CC_BREAK_IF(!fileStream);
CC_BREAK_IF(!fp);
fwrite(data, dataSize, 1, fp);
fclose(fp);
fileStream->write(data, dataSize);
delete fileStream;
return true; return true;
} while (0); } while (0);
@ -571,40 +568,51 @@ FileUtils::Status FileUtils::getContents(const std::string& filename, ResizableB
if (filename.empty()) if (filename.empty())
return Status::NotExists; return Status::NotExists;
auto fs = FileUtils::getInstance(); auto fileUtils = FileUtils::getInstance();
std::string fullPath = fs->fullPathForFilename(filename); const auto fullPath = fileUtils->fullPathForFilename(filename);
if (fullPath.empty())
return Status::NotExists;
FILE *fp = fopen(fullPath.c_str(), "rb"); auto* fileStream = fileUtils->openFileStream(fullPath, FileStream::Mode::READ);
if (!fp) if (!fileStream)
return Status::OpenFailed; return Status::OpenFailed;
struct AutoFileHandle { if (fileStream->seek(0, SEEK_END) != 0)
void operator()(FILE* fp) { {
fclose(fp); delete fileStream;
} return Status::ObtainSizeFailed;
}; }
std::unique_ptr<FILE, AutoFileHandle> autohandle(fp);
struct stat statBuf; const auto size = fileStream->tell();
if (fstat(fileno(fp), &statBuf) == -1) if (size == 0)
return Status::ReadFailed; {
delete fileStream;
return Status::OK;
}
if (!(statBuf.st_mode & S_IFREG)) if (size < 0)
return Status::NotRegularFileType; {
delete fileStream;
return Status::ObtainSizeFailed;
}
size_t size = statBuf.st_size; if (size > ULONG_MAX)
{
delete fileStream;
return Status::TooLarge;
}
buffer->resize(size); buffer->resize(size);
size_t readsize = fread(buffer->buffer(), 1, statBuf.st_size, fp);
if (readsize < size) { fileStream->seek(0, SEEK_SET);
buffer->resize(readsize);
const auto sizeRead = fileStream->read(buffer->buffer(), size);
if (sizeRead < size) {
buffer->resize(sizeRead);
delete fileStream;
return Status::ReadFailed; return Status::ReadFailed;
} }
delete fileStream;
return Status::OK; return Status::OK;
} }

View File

@ -151,7 +151,8 @@ int PosixFileStream::close()
int PosixFileStream::seek(long offset, int origin) int PosixFileStream::seek(long offset, int origin)
{ {
return static_cast<int>(_iof->seek(_handle, offset, origin)); const auto result = _iof->seek(_handle, offset, origin); // this returns -1 for error, and resulting offset on success
return result < 0 ? -1 : 0; // return 0 for success
} }
int PosixFileStream::read(void* buf, unsigned int size) int PosixFileStream::read(void* buf, unsigned int size)

View File

@ -345,11 +345,10 @@ public:
std::string lowerCasePath = fontPath; std::string lowerCasePath = fontPath;
std::transform(lowerCasePath.begin(), lowerCasePath.end(), lowerCasePath.begin(), ::tolower); std::transform(lowerCasePath.begin(), lowerCasePath.end(), lowerCasePath.begin(), ::tolower);
if ( lowerCasePath.find(".ttf") != std::string::npos ) { if ( lowerCasePath.find(".ttf") != std::string::npos ) {
fontPath = cocos2d::FileUtils::getInstance()->fullPathForFilename(fontPath.c_str()); fontPath = cocos2d::FileUtils::getInstance()->fullPathForFilename(fontPath);
auto* fileStream = cocos2d::FileUtils::getInstance()->openFileStream(fontPath, FileStream::Mode::READ);
FILE *f = fopen(fontPath.c_str(), "r"); if ( fileStream ) {
if ( f ) { delete fileStream;
fclose(f);
fontCache.insert(std::pair<std::string, std::string>(family_name, fontPath)); fontCache.insert(std::pair<std::string, std::string>(family_name, fontPath));
return fontPath; return fontPath;
} }

View File

@ -50,6 +50,116 @@ using namespace cocos2d::network;
#define BUFFER_SIZE 8192 #define BUFFER_SIZE 8192
#define MAX_FILENAME 512 #define MAX_FILENAME 512
class AssetManagerZipFileInfo
{
public:
std::string zipFileName{};
};
// unzip overrides to support FileStream
long AssetManager_tell_file_func(voidpf opaque, voidpf stream)
{
if (stream == nullptr)
return -1;
auto* fs = (FileStream*)stream;
return fs->tell();
}
long AssetManager_seek_file_func(voidpf opaque, voidpf stream, uint32_t offset, int origin)
{
if (stream == nullptr)
return -1;
auto* fs = (FileStream*)stream;
return fs->seek((long)offset, origin); // must return 0 for success or -1 for error
}
voidpf AssetManager_open_file_func(voidpf opaque, const char* filename, int mode)
{
FileStream::Mode fsMode;
if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ)
fsMode = FileStream::Mode::READ;
else if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
fsMode = FileStream::Mode::APPEND;
else if (mode & ZLIB_FILEFUNC_MODE_CREATE)
fsMode = FileStream::Mode::WRITE;
else
return nullptr;
return FileUtils::getInstance()->openFileStream(filename, fsMode);
}
voidpf AssetManager_opendisk_file_func(voidpf opaque, voidpf stream, uint32_t number_disk, int mode)
{
if (stream == nullptr)
return nullptr;
const auto zipFileInfo = static_cast<AssetManagerZipFileInfo*>(opaque);
std::string diskFilename = zipFileInfo->zipFileName;
const auto pos = diskFilename.rfind('.', std::string::npos);
if (pos != std::string::npos && pos != 0)
{
const size_t bufferSize = 5;
char extensionBuffer[bufferSize];
snprintf(&extensionBuffer[0], bufferSize, ".z%02u", number_disk + 1);
diskFilename.replace(pos, std::min((size_t)4, zipFileInfo->zipFileName.size() - pos), extensionBuffer);
return AssetManager_open_file_func(opaque, diskFilename.c_str(), mode);
}
return nullptr;
}
uint32_t AssetManager_read_file_func(voidpf opaque, voidpf stream, void* buf, uint32_t size)
{
if (stream == nullptr)
return (uint32_t)-1;
auto* fs = (FileStream*)stream;
return fs->read(buf, size);
}
uint32_t AssetManager_write_file_func(voidpf opaque, voidpf stream, const void* buf, uint32_t size)
{
if (stream == nullptr)
return (uint32_t)-1;
auto* fs = (FileStream*)stream;
return fs->write(buf, size);
}
int AssetManager_close_file_func(voidpf opaque, voidpf stream)
{
if (stream == nullptr)
return -1;
auto* fs = (FileStream*)stream;
return fs->close(); // 0 for success, -1 for error
}
// THis isn't supported by FileStream, so just check if the stream is null and open
int AssetManager_error_file_func(voidpf opaque, voidpf stream)
{
if (stream == nullptr)
{
return -1;
}
auto* fs = (FileStream*)stream;
if (fs->isOpen())
{
return 0;
}
return -1;
}
// End of Overrides
// Implementation of AssetsManager // Implementation of AssetsManager
AssetsManager::AssetsManager(const char* packageUrl/* =nullptr */, const char* versionFileUrl/* =nullptr */, const char* storagePath/* =nullptr */) AssetsManager::AssetsManager(const char* packageUrl/* =nullptr */, const char* versionFileUrl/* =nullptr */, const char* storagePath/* =nullptr */)
@ -259,7 +369,17 @@ bool AssetsManager::uncompress()
{ {
// Open the zip file // Open the zip file
string outFileName = _storagePath + TEMP_PACKAGE_FILE_NAME; string outFileName = _storagePath + TEMP_PACKAGE_FILE_NAME;
unzFile zipfile = unzOpen(outFileName.c_str());
zlib_filefunc_def zipFunctionOverrides;
fillZipFunctionOverrides(zipFunctionOverrides);
AssetManagerZipFileInfo zipFileInfo;
zipFileInfo.zipFileName = outFileName;
zipFunctionOverrides.opaque = &zipFileInfo;
// Open the zip file
unzFile zipfile = unzOpen2(outFileName.c_str(), &zipFunctionOverrides);
if (! zipfile) if (! zipfile)
{ {
CCLOG("can not open downloaded zip file %s", outFileName.c_str()); CCLOG("can not open downloaded zip file %s", outFileName.c_str());
@ -330,10 +450,9 @@ bool AssetsManager::uncompress()
while(index != std::string::npos) while(index != std::string::npos)
{ {
const string dir=_storagePath+fileNameStr.substr(0,index); const string dir=_storagePath+fileNameStr.substr(0,index);
FILE *out = fopen(dir.c_str(), "r"); auto* fsOut = FileUtils::getInstance()->openFileStream(dir, FileStream::Mode::READ);
if (!fsOut)
if(!out)
{ {
if (!FileUtils::getInstance()->createDirectory(dir)) if (!FileUtils::getInstance()->createDirectory(dir))
{ {
@ -348,13 +467,12 @@ bool AssetsManager::uncompress()
} }
else else
{ {
fclose(out); delete fsOut;
} }
startIndex=index+1; startIndex=index+1;
index=fileNameStr.find('/',startIndex); index=fileNameStr.find('/',startIndex);
} }
// Entry is a file, so extract it. // Entry is a file, so extract it.
@ -368,8 +486,8 @@ bool AssetsManager::uncompress()
} }
// Create a file to store current file. // Create a file to store current file.
FILE *out = fopen(fullPath.c_str(), "wb"); auto* fsOut = FileUtils::getInstance()->openFileStream(fullPath, FileStream::Mode::WRITE);
if (! out) if (!fsOut)
{ {
CCLOG("can not open destination file %s", fullPath.c_str()); CCLOG("can not open destination file %s", fullPath.c_str());
unzCloseCurrentFile(zipfile); unzCloseCurrentFile(zipfile);
@ -387,16 +505,17 @@ bool AssetsManager::uncompress()
CCLOG("can not read zip file %s, error code is %d", fileName, error); CCLOG("can not read zip file %s, error code is %d", fileName, error);
unzCloseCurrentFile(zipfile); unzCloseCurrentFile(zipfile);
unzClose(zipfile); unzClose(zipfile);
delete fsOut;
return false; return false;
} }
if (error > 0) if (error > 0)
{ {
fwrite(readBuffer, error, 1, out); fsOut->write(readBuffer, error);
} }
} while(error > 0); } while(error > 0);
fclose(out); delete fsOut;
} }
unzCloseCurrentFile(zipfile); unzCloseCurrentFile(zipfile);
@ -510,4 +629,17 @@ AssetsManager* AssetsManager::create(const char* packageUrl, const char* version
return manager; return manager;
} }
void AssetsManager::fillZipFunctionOverrides(zlib_filefunc_def& zipFunctionOverrides)
{
zipFunctionOverrides.zopen_file = AssetManager_open_file_func;
zipFunctionOverrides.zopendisk_file = AssetManager_opendisk_file_func;
zipFunctionOverrides.zread_file = AssetManager_read_file_func;
zipFunctionOverrides.zwrite_file = AssetManager_write_file_func;
zipFunctionOverrides.ztell_file = AssetManager_tell_file_func;
zipFunctionOverrides.zseek_file = AssetManager_seek_file_func;
zipFunctionOverrides.zclose_file = AssetManager_close_file_func;
zipFunctionOverrides.zerror_file = AssetManager_error_file_func;
zipFunctionOverrides.opaque = nullptr;
}
NS_CC_EXT_END NS_CC_EXT_END

View File

@ -26,6 +26,7 @@
#ifndef __AssetsManager__ #ifndef __AssetsManager__
#define __AssetsManager__ #define __AssetsManager__
#include <ioapi.h>
#include <string> #include <string>
#include <mutex> #include <mutex>
@ -169,6 +170,7 @@ protected:
bool uncompress(); bool uncompress();
void setSearchPath(); void setSearchPath();
void downloadAndUncompress(); void downloadAndUncompress();
void fillZipFunctionOverrides(zlib_filefunc_def& zipFunctionOverrides);
private: private:
//! The path to store downloaded resources. //! The path to store downloaded resources.

View File

@ -53,6 +53,116 @@ NS_CC_EXT_BEGIN
const std::string AssetsManagerEx::VERSION_ID = "@version"; const std::string AssetsManagerEx::VERSION_ID = "@version";
const std::string AssetsManagerEx::MANIFEST_ID = "@manifest"; const std::string AssetsManagerEx::MANIFEST_ID = "@manifest";
class AssetManagerExZipFileInfo
{
public:
std::string zipFileName{};
};
// unzip overrides to support FileStream
long AssetManagerEx_tell_file_func(voidpf opaque, voidpf stream)
{
if (stream == nullptr)
return -1;
auto* fs = (FileStream*)stream;
return fs->tell();
}
long AssetManagerEx_seek_file_func(voidpf opaque, voidpf stream, uint32_t offset, int origin)
{
if (stream == nullptr)
return -1;
auto* fs = (FileStream*)stream;
return fs->seek((long)offset, origin); // must return 0 for success or -1 for error
}
voidpf AssetManagerEx_open_file_func(voidpf opaque, const char* filename, int mode)
{
FileStream::Mode fsMode;
if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ)
fsMode = FileStream::Mode::READ;
else if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
fsMode = FileStream::Mode::APPEND;
else if (mode & ZLIB_FILEFUNC_MODE_CREATE)
fsMode = FileStream::Mode::WRITE;
else
return nullptr;
return FileUtils::getInstance()->openFileStream(filename, fsMode);
}
voidpf AssetManagerEx_opendisk_file_func(voidpf opaque, voidpf stream, uint32_t number_disk, int mode)
{
if (stream == nullptr)
return nullptr;
const auto zipFileInfo = static_cast<AssetManagerExZipFileInfo*>(opaque);
std::string diskFilename = zipFileInfo->zipFileName;
const auto pos = diskFilename.rfind('.', std::string::npos);
if (pos != std::string::npos && pos != 0)
{
const size_t bufferSize = 5;
char extensionBuffer[bufferSize];
snprintf(&extensionBuffer[0], bufferSize, ".z%02u", number_disk + 1);
diskFilename.replace(pos, std::min((size_t)4, zipFileInfo->zipFileName.size() - pos), extensionBuffer);
return AssetManagerEx_open_file_func(opaque, diskFilename.c_str(), mode);
}
return nullptr;
}
uint32_t AssetManagerEx_read_file_func(voidpf opaque, voidpf stream, void* buf, uint32_t size)
{
if (stream == nullptr)
return (uint32_t)-1;
auto* fs = (FileStream*)stream;
return fs->read(buf, size);
}
uint32_t AssetManagerEx_write_file_func(voidpf opaque, voidpf stream, const void* buf, uint32_t size)
{
if (stream == nullptr)
return (uint32_t)-1;
auto* fs = (FileStream*)stream;
return fs->write(buf, size);
}
int AssetManagerEx_close_file_func(voidpf opaque, voidpf stream)
{
if (stream == nullptr)
return -1;
auto* fs = (FileStream*)stream;
return fs->close(); // 0 for success, -1 for error
}
// THis isn't supported by FileStream, so just check if the stream is null and open
int AssetManagerEx_error_file_func(voidpf opaque, voidpf stream)
{
if (stream == nullptr)
{
return -1;
}
auto* fs = (FileStream*)stream;
if (fs->isOpen())
{
return 0;
}
return -1;
}
// End of Overrides
// Implementation of AssetsManagerEx // Implementation of AssetsManagerEx
AssetsManagerEx::AssetsManagerEx(const std::string& manifestUrl, const std::string& storagePath) AssetsManagerEx::AssetsManagerEx(const std::string& manifestUrl, const std::string& storagePath)
@ -314,9 +424,17 @@ bool AssetsManagerEx::decompress(const std::string &zip)
return false; return false;
} }
const std::string rootPath = zip.substr(0, pos+1); const std::string rootPath = zip.substr(0, pos+1);
zlib_filefunc_def zipFunctionOverrides;
fillZipFunctionOverrides(zipFunctionOverrides);
AssetManagerExZipFileInfo zipFileInfo;
zipFileInfo.zipFileName = zip;
zipFunctionOverrides.opaque = &zipFileInfo;
// Open the zip file // Open the zip file
unzFile zipfile = unzOpen(zip.c_str()); unzFile zipfile = unzOpen2(zip.c_str(), &zipFunctionOverrides);
if (! zipfile) if (! zipfile)
{ {
CCLOG("AssetsManagerEx : can not open downloaded zip file %s\n", zip.c_str()); CCLOG("AssetsManagerEx : can not open downloaded zip file %s\n", zip.c_str());
@ -392,8 +510,8 @@ bool AssetsManagerEx::decompress(const std::string &zip)
} }
// Create a file to store current file. // Create a file to store current file.
FILE *out = fopen(fullPath.c_str(), "wb"); auto* fsOut = FileUtils::getInstance()->openFileStream(fullPath, FileStream::Mode::WRITE);
if (!out) if (!fsOut)
{ {
CCLOG("AssetsManagerEx : can not create decompress destination file %s (errno: %d)\n", fullPath.c_str(), errno); CCLOG("AssetsManagerEx : can not create decompress destination file %s (errno: %d)\n", fullPath.c_str(), errno);
unzCloseCurrentFile(zipfile); unzCloseCurrentFile(zipfile);
@ -409,7 +527,7 @@ bool AssetsManagerEx::decompress(const std::string &zip)
if (error < 0) if (error < 0)
{ {
CCLOG("AssetsManagerEx : can not read zip file %s, error code is %d\n", fileName, error); CCLOG("AssetsManagerEx : can not read zip file %s, error code is %d\n", fileName, error);
fclose(out); delete fsOut;
unzCloseCurrentFile(zipfile); unzCloseCurrentFile(zipfile);
unzClose(zipfile); unzClose(zipfile);
return false; return false;
@ -417,11 +535,11 @@ bool AssetsManagerEx::decompress(const std::string &zip)
if (error > 0) if (error > 0)
{ {
fwrite(readBuffer, error, 1, out); fsOut->write(readBuffer, error);
} }
} while(error > 0); } while(error > 0);
fclose(out); delete fsOut;
} }
unzCloseCurrentFile(zipfile); unzCloseCurrentFile(zipfile);
@ -530,7 +648,7 @@ void AssetsManagerEx::downloadVersion()
{ {
_updateState = State::DOWNLOADING_VERSION; _updateState = State::DOWNLOADING_VERSION;
// Download version file asynchronously // Download version file asynchronously
_downloader->createDownloadFileTask(versionUrl, _tempVersionPath, VERSION_ID); _downloader->createDownloadFileTask(versionUrl, _tempVersionPath, "", VERSION_ID);
} }
// No version file found // No version file found
else else
@ -598,7 +716,7 @@ void AssetsManagerEx::downloadManifest()
{ {
_updateState = State::DOWNLOADING_MANIFEST; _updateState = State::DOWNLOADING_MANIFEST;
// Download version file asynchronously // Download version file asynchronously
_downloader->createDownloadFileTask(manifestUrl, _tempManifestPath, MANIFEST_ID); _downloader->createDownloadFileTask(manifestUrl, _tempManifestPath, "", MANIFEST_ID);
} }
// No manifest file found // No manifest file found
else else
@ -1147,7 +1265,7 @@ void AssetsManagerEx::queueDowload()
_currConcurrentTask++; _currConcurrentTask++;
DownloadUnit& unit = _downloadUnits[key]; DownloadUnit& unit = _downloadUnits[key];
_fileUtils->createDirectory(basename(unit.storagePath)); _fileUtils->createDirectory(basename(unit.storagePath));
_downloader->createDownloadFileTask(unit.srcUrl, unit.storagePath, unit.customId); _downloader->createDownloadFileTask(unit.srcUrl, unit.storagePath, "", unit.customId);
_tempManifest->setAssetDownloadState(key, Manifest::DownloadState::DOWNLOADING); _tempManifest->setAssetDownloadState(key, Manifest::DownloadState::DOWNLOADING);
} }
@ -1176,4 +1294,17 @@ void AssetsManagerEx::onDownloadUnitsFinished()
} }
} }
void AssetsManagerEx::fillZipFunctionOverrides(zlib_filefunc_def& zipFunctionOverrides)
{
zipFunctionOverrides.zopen_file = AssetManagerEx_open_file_func;
zipFunctionOverrides.zopendisk_file = AssetManagerEx_opendisk_file_func;
zipFunctionOverrides.zread_file = AssetManagerEx_read_file_func;
zipFunctionOverrides.zwrite_file = AssetManagerEx_write_file_func;
zipFunctionOverrides.ztell_file = AssetManagerEx_tell_file_func;
zipFunctionOverrides.zseek_file = AssetManagerEx_seek_file_func;
zipFunctionOverrides.zclose_file = AssetManagerEx_close_file_func;
zipFunctionOverrides.zerror_file = AssetManagerEx_error_file_func;
zipFunctionOverrides.opaque = nullptr;
}
NS_CC_EXT_END NS_CC_EXT_END

View File

@ -26,6 +26,7 @@
#ifndef __AssetsManagerEx__ #ifndef __AssetsManagerEx__
#define __AssetsManagerEx__ #define __AssetsManagerEx__
#include <ioapi.h>
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
@ -219,7 +220,8 @@ private:
// Called when one DownloadUnits finished // Called when one DownloadUnits finished
void onDownloadUnitsFinished(); void onDownloadUnitsFinished();
void fillZipFunctionOverrides(zlib_filefunc_def &zipFunctionOverrides);
//! The event of the current AssetsManagerEx in event dispatcher //! The event of the current AssetsManagerEx in event dispatcher
std::string _eventName; std::string _eventName;
@ -263,7 +265,7 @@ private:
//! Remote manifest //! Remote manifest
Manifest *_remoteManifest = nullptr; Manifest *_remoteManifest = nullptr;
//! Whether user have requested to update //! Whether user have requested to update
enum class UpdateEntry : char enum class UpdateEntry : char
{ {