MNN/source/core/FileLoader.cpp

126 lines
3.2 KiB
C++
Raw Normal View History

//
// FileLoader.cpp
// MNN
//
// Created by MNN on 2019/07/04.
// Copyright © 2018, Alibaba Group Holding Limited
//
2019-12-27 22:16:57 +08:00
#include "core/FileLoader.hpp"
#if defined(_MSC_VER)
#include "Windows.h"
#endif
namespace MNN {
FileLoader::FileLoader(const char* file) {
#if defined(_MSC_VER)
wchar_t wFilename[1024];
2021-04-08 15:34:23 +08:00
if (0 == MultiByteToWideChar(CP_ACP, 0, file, -1, wFilename, sizeof(wFilename))) {
2020-11-05 16:41:56 +08:00
mFile = nullptr;
return;
}
#if _MSC_VER >= 1400
if (0 != _wfopen_s(&mFile, wFilename, L"rb")) {
2020-11-05 16:41:56 +08:00
mFile = nullptr;
return;
}
#else
mFile = _wfopen(wFilename, L"rb");
#endif
#else
mFile = fopen(file, "rb");
#endif
2021-09-18 15:52:30 +08:00
mFilePath = file;
}
FileLoader::~FileLoader() {
if (nullptr != mFile) {
fclose(mFile);
}
for (auto iter : mBlocks) {
MNNMemoryFreeAlign(iter.second);
}
}
bool FileLoader::read() {
auto block = MNNMemoryAllocAlign(gCacheSize, MNN_MEMORY_ALIGN_DEFAULT);
if (nullptr == block) {
MNN_PRINT("Memory Alloc Failed\n");
return false;
}
auto size = fread(block, 1, gCacheSize, mFile);
mTotalSize = size;
mBlocks.push_back(std::make_pair(size, block));
while (size == gCacheSize) {
block = MNNMemoryAllocAlign(gCacheSize, MNN_MEMORY_ALIGN_DEFAULT);
if (nullptr == block) {
MNN_PRINT("Memory Alloc Failed\n");
return false;
}
size = fread(block, 1, gCacheSize, mFile);
if (size > gCacheSize) {
MNN_PRINT("Read file Error\n");
MNNMemoryFreeAlign(block);
return false;
}
mTotalSize += size;
mBlocks.push_back(std::make_pair(size, block));
}
if (ferror(mFile)) {
return false;
}
return true;
}
2022-01-04 10:50:40 +08:00
bool FileLoader::write(const char* filePath, std::pair<const void*, size_t> cacheInfo) {
2021-09-26 20:40:03 +08:00
FILE* f = fopen(filePath, "wb");
2021-09-18 15:52:30 +08:00
if (nullptr == f) {
2021-09-26 20:40:03 +08:00
MNN_ERROR("Open %s error\n", filePath);
2021-09-18 15:52:30 +08:00
return false;
}
// Write Cache
static const size_t block = 4096;
size_t totalSize = cacheInfo.second;
size_t blockSize = UP_DIV(totalSize, block);
for (size_t i = 0; i < blockSize; ++i) {
size_t sta = block * i;
2021-09-26 20:40:03 +08:00
size_t fin = (sta + block >= totalSize) ? totalSize : (sta + block);
2021-09-18 15:52:30 +08:00
if (fin > sta) {
auto realSize = fwrite((const char*)(cacheInfo.first) + sta, 1, fin - sta, f);
if (realSize != fin - sta) {
2021-09-26 20:40:03 +08:00
MNN_ERROR("Write %s error\n", filePath);
fclose(f);
2021-09-18 15:52:30 +08:00
return false;
}
}
}
fclose(f);
return true;
}
bool FileLoader::merge(AutoStorage<uint8_t>& buffer) {
buffer.reset((int)mTotalSize);
if (buffer.get() == nullptr) {
MNN_PRINT("Memory Alloc Failed\n");
return false;
}
auto dst = buffer.get();
int offset = 0;
for (auto iter : mBlocks) {
::memcpy(dst + offset, iter.second, iter.first);
offset += iter.first;
}
return true;
}
2022-12-30 15:18:58 +08:00
int FileLoader::offset(int64_t offset) {
return fseek(mFile, offset, SEEK_SET);
}
bool FileLoader::read(char* buffer, int64_t size) {
return fread(buffer, 1, size, mFile) == size;
}
} // namespace MNN