chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,328 @@
|
||||
//
|
||||
// MNNFileUtils.cpp
|
||||
// MNN
|
||||
//
|
||||
// Created by MNN on 2024/07/25.
|
||||
// Copyright © 2018, Alibaba Group Holding Limited
|
||||
//
|
||||
|
||||
#include <cstring>
|
||||
#include "MNNFileUtils.h"
|
||||
|
||||
std::string MNNFilePathConcat(std::string prefix, std::string suffix) {
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)
|
||||
return prefix + "\\" + suffix;
|
||||
#else
|
||||
return prefix + "/" + suffix;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool MNNDirExist(const char * path) {
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)
|
||||
DWORD file_attributes = GetFileAttributes(path);
|
||||
return (file_attributes != INVALID_FILE_ATTRIBUTES) && (file_attributes & FILE_ATTRIBUTE_DIRECTORY);
|
||||
#else
|
||||
struct stat info;
|
||||
return (stat(path, &info) == 0) && (info.st_mode & S_IFDIR);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool MNNFileExist(const char * file_name)
|
||||
{
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)
|
||||
return _access(file_name, 0) == 0;
|
||||
#else
|
||||
return access(file_name, F_OK) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool MNNCreateDir(const char * path) {
|
||||
if (MNNDirExist(path)) {
|
||||
return true;
|
||||
}
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)
|
||||
if (CreateDirectory(path, NULL) || ERROR_ALREADY_EXISTS == GetLastError()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
if (mkdir(path, 0755) == 0) {
|
||||
return true;
|
||||
}
|
||||
return MNNDirExist(path);
|
||||
#endif
|
||||
}
|
||||
|
||||
file_t MNNCreateFile(const char * file_name)
|
||||
{
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)
|
||||
HANDLE hd = CreateFile(
|
||||
file_name, // File Name
|
||||
GENERIC_READ | GENERIC_WRITE, // Read and Write
|
||||
0, // No Sharing
|
||||
NULL, // No Security
|
||||
CREATE_ALWAYS, // Create the file and cover the existing file
|
||||
FILE_ATTRIBUTE_NORMAL, // Normal Attribute
|
||||
NULL // No Template
|
||||
);
|
||||
if (hd == INVALID_HANDLE_VALUE) {
|
||||
MNN_PRINT("Failed to create the file: %s\n", file_name);
|
||||
return INVALID_FILE;
|
||||
}
|
||||
return hd;
|
||||
#else
|
||||
int fd = open(
|
||||
file_name, // File Name
|
||||
O_RDWR | O_CREAT | O_TRUNC, // Read and Write and Create the file and cover existing file
|
||||
0666 // Read and Write Permission for Everyone
|
||||
);
|
||||
if (fd == -1) {
|
||||
MNN_PRINT("Failed to create the file: %s\n", file_name);
|
||||
return INVALID_FILE;
|
||||
}
|
||||
return fd;
|
||||
#endif
|
||||
}
|
||||
|
||||
file_t MNNOpenFile(const char * file_name, uint32_t flags)
|
||||
{
|
||||
if (!MNNFileExist(file_name)) {
|
||||
MNN_PRINT("File not exist: %s\n", file_name);
|
||||
return INVALID_FILE;
|
||||
}
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)
|
||||
DWORD mode = 0;
|
||||
if (flags & MNN_FILE_READ) {
|
||||
mode |= GENERIC_READ;
|
||||
}
|
||||
if (flags & MNN_FILE_WRITE) {
|
||||
mode |= GENERIC_WRITE;
|
||||
}
|
||||
HANDLE hd = CreateFile(
|
||||
file_name, // File Name
|
||||
mode, // Opening Mode
|
||||
0, // No Sharing
|
||||
NULL, // No Security
|
||||
OPEN_EXISTING, // Only Open Existing File
|
||||
FILE_ATTRIBUTE_NORMAL, // Normal Attribute
|
||||
NULL // No Template
|
||||
);
|
||||
if (hd == INVALID_HANDLE_VALUE) {
|
||||
MNN_PRINT("Failed to open the file: %s\n", file_name);
|
||||
return INVALID_FILE;
|
||||
}
|
||||
return hd;
|
||||
#else
|
||||
int mode = 0;
|
||||
if (flags & MNN_FILE_READ) {
|
||||
mode = O_RDONLY;
|
||||
}
|
||||
if (flags & MNN_FILE_WRITE) {
|
||||
mode = O_RDWR;
|
||||
}
|
||||
int fd = open(file_name, mode);
|
||||
if (fd == -1) {
|
||||
MNN_PRINT("Failed to open the file: %s\n", file_name);
|
||||
return INVALID_FILE;
|
||||
}
|
||||
return fd;
|
||||
#endif
|
||||
}
|
||||
|
||||
ErrorCode MNNCloseFile(file_t file)
|
||||
{
|
||||
if (file == INVALID_FILE) {
|
||||
return FILE_NOT_EXIST;
|
||||
}
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)
|
||||
if (!CloseHandle(file)) {
|
||||
return FILE_CLOSE_FAILED;
|
||||
}
|
||||
#else
|
||||
if (-1 == close(file)) {
|
||||
return FILE_CLOSE_FAILED;
|
||||
}
|
||||
#endif
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
ErrorCode MNNRemoveFile(const char * file_name)
|
||||
{
|
||||
if (!MNNFileExist(file_name)) {
|
||||
return FILE_NOT_EXIST;
|
||||
}
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)
|
||||
if (!DeleteFile(file_name)) {
|
||||
return FILE_REMOVE_FAILED;
|
||||
}
|
||||
#else
|
||||
if (-1 == unlink(file_name)) {
|
||||
return FILE_REMOVE_FAILED;
|
||||
}
|
||||
#endif
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
size_t MNNGetFileSize(file_t file)
|
||||
{
|
||||
if (file == INVALID_FILE) {
|
||||
return INVALID_SIZE;
|
||||
}
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)
|
||||
LARGE_INTEGER fileSize;
|
||||
if (!GetFileSizeEx(file, &fileSize)) {
|
||||
return (size_t)(-1);
|
||||
} else {
|
||||
return (size_t)(fileSize.QuadPart);
|
||||
}
|
||||
#else
|
||||
struct stat file_stat;
|
||||
if (fstat(file, &file_stat) == -1) {
|
||||
return (size_t)(-1);
|
||||
} else {
|
||||
return file_stat.st_size;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
ErrorCode MNNSetFileSize(file_t file, size_t aimed_size)
|
||||
{
|
||||
if (file == INVALID_FILE) {
|
||||
return FILE_NOT_EXIST;
|
||||
}
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)
|
||||
LARGE_INTEGER size;
|
||||
size.QuadPart = aimed_size;
|
||||
bool success = SetFilePointerEx(file, size, NULL, FILE_BEGIN);
|
||||
if (!success) {
|
||||
return FILE_RESIZE_FAILED;
|
||||
}
|
||||
success = SetEndOfFile(file);
|
||||
if (!success) {
|
||||
return FILE_RESIZE_FAILED;
|
||||
}
|
||||
return NO_ERROR;
|
||||
#else
|
||||
if (-1 == ftruncate(file, aimed_size)) {
|
||||
return FILE_RESIZE_FAILED;
|
||||
}
|
||||
return NO_ERROR;
|
||||
#endif
|
||||
}
|
||||
|
||||
size_t MNNReadFile(file_t file, void * buf, size_t bytes)
|
||||
{
|
||||
if (file == INVALID_FILE || buf == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)
|
||||
DWORD readbytes = 0;
|
||||
if (ReadFile(file, buf, bytes, &readbytes, NULL)) {
|
||||
return readbytes;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
return read(file, buf, bytes);
|
||||
#endif
|
||||
}
|
||||
|
||||
size_t MNNWriteFile(file_t file, void * buf, size_t bytes)
|
||||
{
|
||||
if (file == INVALID_FILE || buf == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)
|
||||
DWORD writebytes = 0;
|
||||
if (WriteFile(file, buf, bytes, &writebytes, NULL)) {
|
||||
return writebytes;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
return write(file, buf, bytes);
|
||||
#endif
|
||||
}
|
||||
|
||||
ErrorCode MNNSetFilePointer(file_t file, size_t offset)
|
||||
{
|
||||
if (file == INVALID_FILE) {
|
||||
return FILE_NOT_EXIST;
|
||||
}
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)
|
||||
LARGE_INTEGER liDistanceToMove;
|
||||
liDistanceToMove.QuadPart = offset;
|
||||
if (SetFilePointerEx(file, liDistanceToMove, NULL, FILE_BEGIN)) {
|
||||
return NO_ERROR;
|
||||
} else {
|
||||
return FILE_SEEK_FAILED;
|
||||
}
|
||||
#else
|
||||
if (-1 == lseek(file, offset, SEEK_SET)) {
|
||||
return FILE_SEEK_FAILED;
|
||||
} else {
|
||||
return NO_ERROR;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void * MNNMmapFile(file_t file, size_t size, bool onlyRead)
|
||||
{
|
||||
if (file == INVALID_FILE || MNNGetFileSize(file) < size) {
|
||||
return nullptr;
|
||||
}
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)
|
||||
HANDLE hFileMapping = CreateFileMapping(file, NULL, PAGE_READWRITE, (size >> 32) & 0xffffffff, size & 0xffffffff, NULL);
|
||||
if (hFileMapping == NULL) {
|
||||
MNN_ERROR("MNN: Mmap failed\n");
|
||||
return nullptr;
|
||||
}
|
||||
auto mode = FILE_MAP_READ | FILE_MAP_WRITE;
|
||||
if (onlyRead) {
|
||||
mode = FILE_MAP_READ;
|
||||
}
|
||||
void * addr = MapViewOfFile(hFileMapping, mode, 0, 0, size);
|
||||
CloseHandle(hFileMapping);
|
||||
return addr;
|
||||
#else
|
||||
auto mode = PROT_READ | PROT_WRITE;
|
||||
if (onlyRead) {
|
||||
mode = PROT_READ;
|
||||
}
|
||||
void * addr = mmap(NULL, size, mode, MAP_SHARED, file, 0);
|
||||
if (addr == MAP_FAILED) {
|
||||
MNN_ERROR("MNN: Mmap failed\n");
|
||||
return nullptr;
|
||||
}
|
||||
return addr;
|
||||
#endif
|
||||
}
|
||||
|
||||
ErrorCode MNNUnmapFile(void * addr, size_t size)
|
||||
{
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)
|
||||
if (!UnmapViewOfFile(addr)) {
|
||||
return FILE_UNMAP_FAILED;
|
||||
}
|
||||
#else
|
||||
if (-1 == munmap(addr, size)) {
|
||||
return FILE_UNMAP_FAILED;
|
||||
}
|
||||
#endif
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
ErrorCode MNNMmapSync(void * addr, size_t size)
|
||||
{
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)
|
||||
if (!FlushViewOfFile(addr, 0)) {
|
||||
return FILE_UNMAP_FAILED;
|
||||
}
|
||||
#else
|
||||
if (-1 == msync(addr, size, MS_SYNC)) {
|
||||
return FILE_UNMAP_FAILED;
|
||||
}
|
||||
#endif
|
||||
return NO_ERROR;
|
||||
}
|
||||
Reference in New Issue
Block a user