mirror of https://github.com/axmolengine/axmol.git
Merge pull request #342 from rh101/vfs-support
Ensure FileStream is used for file access where possible
This commit is contained in:
commit
5664291631
|
@ -183,7 +183,8 @@ bool FontFreeType::createFontObject(const std::string &fontName, float fontSize)
|
|||
std::unique_ptr<FT_StreamRec> fts(new FT_StreamRec());
|
||||
fts->read = ft_stream_read_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);
|
||||
|
||||
fts->descriptor.pointer = fs;
|
||||
|
|
|
@ -68,7 +68,7 @@ protected:
|
|||
AudioDecoderOgg();
|
||||
~AudioDecoderOgg();
|
||||
|
||||
FileStream* _fileStream;
|
||||
FileStream* _fileStream = nullptr;
|
||||
OggVorbis_File _vf;
|
||||
|
||||
friend class AudioDecoderManager;
|
||||
|
|
|
@ -61,7 +61,7 @@ namespace cocos2d {
|
|||
|
||||
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
|
||||
static bool __mp3Inited = false;
|
||||
|
|
|
@ -44,8 +44,7 @@ namespace cocos2d {
|
|||
|
||||
static int ov_fseek_r(void * handle, ogg_int64_t offset, int whence)
|
||||
{
|
||||
auto n = ((FileStream*)handle)->seek(offset, whence);
|
||||
return n >= 0 ? 0 : -1;
|
||||
return ((FileStream*)handle)->seek(offset, whence) < 0 ? -1 : 0;
|
||||
}
|
||||
|
||||
static long ov_ftell_r(void * handle)
|
||||
|
|
|
@ -141,7 +141,7 @@ namespace cocos2d {
|
|||
ALOGW("The wav format %d doesn't supported currently!", (int)fmtInfo.AudioFormat);
|
||||
fileStream->close();
|
||||
assert(false);
|
||||
return false;;
|
||||
return false;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1491,8 +1491,8 @@ void Console::commandUpload(int fd)
|
|||
static std::string writablePath = FileUtils::getInstance()->getWritablePath();
|
||||
std::string filepath = writablePath + std::string(buf);
|
||||
|
||||
FILE* fp = fopen(filepath.c_str(), "wb");
|
||||
if(!fp)
|
||||
auto* fs = FileUtils::getInstance()->openFileStream(filepath, FileStream::Mode::WRITE);
|
||||
if(!fs)
|
||||
{
|
||||
const char err[] = "can't create file!\n";
|
||||
Console::Utility::sendToConsole(fd, err, strlen(err));
|
||||
|
@ -1517,11 +1517,12 @@ void Console::commandUpload(int fd)
|
|||
int dt = base64Decode(in, 4, &decode);
|
||||
if (dt > 0)
|
||||
{
|
||||
fwrite(decode, dt, 1, fp);
|
||||
fs->write(decode, dt);
|
||||
}
|
||||
free(decode);
|
||||
}
|
||||
fclose(fp);
|
||||
fs->close();
|
||||
delete fs;
|
||||
}
|
||||
|
||||
void Console::commandVersion(int fd, const std::string& /*args*/)
|
||||
|
|
|
@ -154,7 +154,8 @@ public:
|
|||
_checksumFileName = filename + ".chksum";
|
||||
|
||||
_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);
|
||||
} else {
|
||||
_fsMd5->seek(0, SEEK_SET);
|
||||
|
@ -819,10 +820,10 @@ void DownloaderCURL::_onDownloadFinished(TaskWrapper&& wrapper, int checkState)
|
|||
|
||||
if (checkState & kCheckSumStateSucceed) // No need download
|
||||
{
|
||||
FileStream* fsOrigin =
|
||||
FileUtils::getInstance()->openFileStream(coTask._fileName, FileStream::Mode::READ);
|
||||
auto* fsOrigin = pFileUtils->openFileStream(coTask._fileName, FileStream::Mode::READ);
|
||||
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.totalBytesReceived = task.progressInfo.totalBytesExpected;
|
||||
task.progressInfo.speedInBytes = task.progressInfo.totalBytesExpected;
|
||||
|
|
|
@ -409,7 +409,7 @@ void HttpClient::enableCookies(const char* cookieFile)
|
|||
}
|
||||
else
|
||||
{
|
||||
_cookieFilename = (FileUtils::getInstance()->getWritablePath() + "cookieFile.txt");
|
||||
_cookieFilename = (FileUtils::getInstance()->getNativeWritableAbsolutePath() + "cookieFile.txt");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
const char* mode = "wb";
|
||||
|
||||
CCASSERT(!fullPath.empty() && dataSize > 0, "Invalid parameters.");
|
||||
|
||||
auto fileutils = FileUtils::getInstance();
|
||||
auto* fileUtils = FileUtils::getInstance();
|
||||
do
|
||||
{
|
||||
auto* fileStream = fileUtils->openFileStream(fullPath, FileStream::Mode::WRITE);
|
||||
// Read the file from hardware
|
||||
FILE* fp = fopen(fullPath.c_str(), mode);
|
||||
CC_BREAK_IF(!fp);
|
||||
fwrite(data, dataSize, 1, fp);
|
||||
|
||||
fclose(fp);
|
||||
CC_BREAK_IF(!fileStream);
|
||||
|
||||
fileStream->write(data, dataSize);
|
||||
delete fileStream;
|
||||
return true;
|
||||
} while (0);
|
||||
|
||||
|
@ -571,40 +568,51 @@ FileUtils::Status FileUtils::getContents(const std::string& filename, ResizableB
|
|||
if (filename.empty())
|
||||
return Status::NotExists;
|
||||
|
||||
auto fs = FileUtils::getInstance();
|
||||
auto fileUtils = FileUtils::getInstance();
|
||||
|
||||
std::string fullPath = fs->fullPathForFilename(filename);
|
||||
if (fullPath.empty())
|
||||
return Status::NotExists;
|
||||
const auto fullPath = fileUtils->fullPathForFilename(filename);
|
||||
|
||||
FILE *fp = fopen(fullPath.c_str(), "rb");
|
||||
if (!fp)
|
||||
auto* fileStream = fileUtils->openFileStream(fullPath, FileStream::Mode::READ);
|
||||
if (!fileStream)
|
||||
return Status::OpenFailed;
|
||||
|
||||
struct AutoFileHandle {
|
||||
void operator()(FILE* fp) {
|
||||
fclose(fp);
|
||||
}
|
||||
};
|
||||
std::unique_ptr<FILE, AutoFileHandle> autohandle(fp);
|
||||
if (fileStream->seek(0, SEEK_END) != 0)
|
||||
{
|
||||
delete fileStream;
|
||||
return Status::ObtainSizeFailed;
|
||||
}
|
||||
|
||||
struct stat statBuf;
|
||||
if (fstat(fileno(fp), &statBuf) == -1)
|
||||
return Status::ReadFailed;
|
||||
const auto size = fileStream->tell();
|
||||
if (size == 0)
|
||||
{
|
||||
delete fileStream;
|
||||
return Status::OK;
|
||||
}
|
||||
|
||||
if (!(statBuf.st_mode & S_IFREG))
|
||||
return Status::NotRegularFileType;
|
||||
if (size < 0)
|
||||
{
|
||||
delete fileStream;
|
||||
return Status::ObtainSizeFailed;
|
||||
}
|
||||
|
||||
size_t size = statBuf.st_size;
|
||||
if (size > ULONG_MAX)
|
||||
{
|
||||
delete fileStream;
|
||||
return Status::TooLarge;
|
||||
}
|
||||
|
||||
buffer->resize(size);
|
||||
size_t readsize = fread(buffer->buffer(), 1, statBuf.st_size, fp);
|
||||
|
||||
if (readsize < size) {
|
||||
buffer->resize(readsize);
|
||||
fileStream->seek(0, SEEK_SET);
|
||||
|
||||
const auto sizeRead = fileStream->read(buffer->buffer(), size);
|
||||
if (sizeRead < size) {
|
||||
buffer->resize(sizeRead);
|
||||
delete fileStream;
|
||||
return Status::ReadFailed;
|
||||
}
|
||||
|
||||
delete fileStream;
|
||||
return Status::OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -151,7 +151,8 @@ int PosixFileStream::close()
|
|||
|
||||
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)
|
||||
|
|
|
@ -345,11 +345,10 @@ public:
|
|||
std::string lowerCasePath = fontPath;
|
||||
std::transform(lowerCasePath.begin(), lowerCasePath.end(), lowerCasePath.begin(), ::tolower);
|
||||
if ( lowerCasePath.find(".ttf") != std::string::npos ) {
|
||||
fontPath = cocos2d::FileUtils::getInstance()->fullPathForFilename(fontPath.c_str());
|
||||
|
||||
FILE *f = fopen(fontPath.c_str(), "r");
|
||||
if ( f ) {
|
||||
fclose(f);
|
||||
fontPath = cocos2d::FileUtils::getInstance()->fullPathForFilename(fontPath);
|
||||
auto* fileStream = cocos2d::FileUtils::getInstance()->openFileStream(fontPath, FileStream::Mode::READ);
|
||||
if ( fileStream ) {
|
||||
delete fileStream;
|
||||
fontCache.insert(std::pair<std::string, std::string>(family_name, fontPath));
|
||||
return fontPath;
|
||||
}
|
||||
|
|
|
@ -50,6 +50,116 @@ using namespace cocos2d::network;
|
|||
#define BUFFER_SIZE 8192
|
||||
#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
|
||||
|
||||
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
|
||||
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)
|
||||
{
|
||||
CCLOG("can not open downloaded zip file %s", outFileName.c_str());
|
||||
|
@ -330,10 +450,9 @@ bool AssetsManager::uncompress()
|
|||
while(index != std::string::npos)
|
||||
{
|
||||
const string dir=_storagePath+fileNameStr.substr(0,index);
|
||||
|
||||
FILE *out = fopen(dir.c_str(), "r");
|
||||
|
||||
if(!out)
|
||||
|
||||
auto* fsOut = FileUtils::getInstance()->openFileStream(dir, FileStream::Mode::READ);
|
||||
if (!fsOut)
|
||||
{
|
||||
if (!FileUtils::getInstance()->createDirectory(dir))
|
||||
{
|
||||
|
@ -348,13 +467,12 @@ bool AssetsManager::uncompress()
|
|||
}
|
||||
else
|
||||
{
|
||||
fclose(out);
|
||||
delete fsOut;
|
||||
}
|
||||
|
||||
startIndex=index+1;
|
||||
|
||||
index=fileNameStr.find('/',startIndex);
|
||||
|
||||
}
|
||||
|
||||
// Entry is a file, so extract it.
|
||||
|
@ -368,8 +486,8 @@ bool AssetsManager::uncompress()
|
|||
}
|
||||
|
||||
// Create a file to store current file.
|
||||
FILE *out = fopen(fullPath.c_str(), "wb");
|
||||
if (! out)
|
||||
auto* fsOut = FileUtils::getInstance()->openFileStream(fullPath, FileStream::Mode::WRITE);
|
||||
if (!fsOut)
|
||||
{
|
||||
CCLOG("can not open destination file %s", fullPath.c_str());
|
||||
unzCloseCurrentFile(zipfile);
|
||||
|
@ -387,16 +505,17 @@ bool AssetsManager::uncompress()
|
|||
CCLOG("can not read zip file %s, error code is %d", fileName, error);
|
||||
unzCloseCurrentFile(zipfile);
|
||||
unzClose(zipfile);
|
||||
delete fsOut;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (error > 0)
|
||||
{
|
||||
fwrite(readBuffer, error, 1, out);
|
||||
fsOut->write(readBuffer, error);
|
||||
}
|
||||
} while(error > 0);
|
||||
|
||||
fclose(out);
|
||||
|
||||
delete fsOut;
|
||||
}
|
||||
|
||||
unzCloseCurrentFile(zipfile);
|
||||
|
@ -510,4 +629,17 @@ AssetsManager* AssetsManager::create(const char* packageUrl, const char* version
|
|||
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
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#ifndef __AssetsManager__
|
||||
#define __AssetsManager__
|
||||
|
||||
#include <ioapi.h>
|
||||
#include <string>
|
||||
|
||||
#include <mutex>
|
||||
|
@ -169,6 +170,7 @@ protected:
|
|||
bool uncompress();
|
||||
void setSearchPath();
|
||||
void downloadAndUncompress();
|
||||
void fillZipFunctionOverrides(zlib_filefunc_def& zipFunctionOverrides);
|
||||
|
||||
private:
|
||||
//! The path to store downloaded resources.
|
||||
|
|
|
@ -53,6 +53,116 @@ NS_CC_EXT_BEGIN
|
|||
const std::string AssetsManagerEx::VERSION_ID = "@version";
|
||||
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
|
||||
|
||||
AssetsManagerEx::AssetsManagerEx(const std::string& manifestUrl, const std::string& storagePath)
|
||||
|
@ -314,9 +424,17 @@ bool AssetsManagerEx::decompress(const std::string &zip)
|
|||
return false;
|
||||
}
|
||||
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
|
||||
unzFile zipfile = unzOpen(zip.c_str());
|
||||
unzFile zipfile = unzOpen2(zip.c_str(), &zipFunctionOverrides);
|
||||
if (! zipfile)
|
||||
{
|
||||
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.
|
||||
FILE *out = fopen(fullPath.c_str(), "wb");
|
||||
if (!out)
|
||||
auto* fsOut = FileUtils::getInstance()->openFileStream(fullPath, FileStream::Mode::WRITE);
|
||||
if (!fsOut)
|
||||
{
|
||||
CCLOG("AssetsManagerEx : can not create decompress destination file %s (errno: %d)\n", fullPath.c_str(), errno);
|
||||
unzCloseCurrentFile(zipfile);
|
||||
|
@ -409,7 +527,7 @@ bool AssetsManagerEx::decompress(const std::string &zip)
|
|||
if (error < 0)
|
||||
{
|
||||
CCLOG("AssetsManagerEx : can not read zip file %s, error code is %d\n", fileName, error);
|
||||
fclose(out);
|
||||
delete fsOut;
|
||||
unzCloseCurrentFile(zipfile);
|
||||
unzClose(zipfile);
|
||||
return false;
|
||||
|
@ -417,11 +535,11 @@ bool AssetsManagerEx::decompress(const std::string &zip)
|
|||
|
||||
if (error > 0)
|
||||
{
|
||||
fwrite(readBuffer, error, 1, out);
|
||||
fsOut->write(readBuffer, error);
|
||||
}
|
||||
} while(error > 0);
|
||||
|
||||
fclose(out);
|
||||
delete fsOut;
|
||||
}
|
||||
|
||||
unzCloseCurrentFile(zipfile);
|
||||
|
@ -530,7 +648,7 @@ void AssetsManagerEx::downloadVersion()
|
|||
{
|
||||
_updateState = State::DOWNLOADING_VERSION;
|
||||
// Download version file asynchronously
|
||||
_downloader->createDownloadFileTask(versionUrl, _tempVersionPath, VERSION_ID);
|
||||
_downloader->createDownloadFileTask(versionUrl, _tempVersionPath, "", VERSION_ID);
|
||||
}
|
||||
// No version file found
|
||||
else
|
||||
|
@ -598,7 +716,7 @@ void AssetsManagerEx::downloadManifest()
|
|||
{
|
||||
_updateState = State::DOWNLOADING_MANIFEST;
|
||||
// Download version file asynchronously
|
||||
_downloader->createDownloadFileTask(manifestUrl, _tempManifestPath, MANIFEST_ID);
|
||||
_downloader->createDownloadFileTask(manifestUrl, _tempManifestPath, "", MANIFEST_ID);
|
||||
}
|
||||
// No manifest file found
|
||||
else
|
||||
|
@ -1147,7 +1265,7 @@ void AssetsManagerEx::queueDowload()
|
|||
_currConcurrentTask++;
|
||||
DownloadUnit& unit = _downloadUnits[key];
|
||||
_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);
|
||||
}
|
||||
|
@ -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
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#ifndef __AssetsManagerEx__
|
||||
#define __AssetsManagerEx__
|
||||
|
||||
#include <ioapi.h>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
@ -219,7 +220,8 @@ private:
|
|||
|
||||
// Called when one DownloadUnits finished
|
||||
void onDownloadUnitsFinished();
|
||||
|
||||
void fillZipFunctionOverrides(zlib_filefunc_def &zipFunctionOverrides);
|
||||
|
||||
//! The event of the current AssetsManagerEx in event dispatcher
|
||||
std::string _eventName;
|
||||
|
||||
|
@ -263,7 +265,7 @@ private:
|
|||
|
||||
//! Remote manifest
|
||||
Manifest *_remoteManifest = nullptr;
|
||||
|
||||
|
||||
//! Whether user have requested to update
|
||||
enum class UpdateEntry : char
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue