123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- #include "il2cpp-config.h"
- #if IL2CPP_USE_GENERIC_MEMORY_MAPPED_FILE
- #include "os/File.h"
- #include "os/MemoryMappedFile.h"
- #include "os/Mutex.h"
- #include "utils/dynamic_array.h"
- #include "utils/Memory.h"
- #include "Baselib.h"
- #include "Cpp/ReentrantLock.h"
- namespace il2cpp
- {
- namespace os
- {
- struct MemoryFileData
- {
- MemoryFileData(const char* name, int64_t dataSize)
- : size(dataSize)
- {
- size_t nameSize = strlen(name);
- mapName = (char*)IL2CPP_MALLOC(nameSize + 1);
- strcpy(mapName, name);
- handle = IL2CPP_MALLOC_ZERO((size_t)dataSize);
- }
- ~MemoryFileData()
- {
- IL2CPP_FREE(mapName);
- IL2CPP_FREE(handle);
- }
- char* mapName;
- void* handle;
- int64_t size;
- };
- static baselib::ReentrantLock s_Mutex;
- static il2cpp::utils::dynamic_array<MemoryFileData*> s_MemoryFiles;
- static il2cpp::utils::dynamic_array<void*> s_MemoryFileViews;
- static bool IsMemoryFile(void* possibleMemoryFile)
- {
- os::FastAutoLock lock(&s_Mutex);
- for (il2cpp::utils::dynamic_array<MemoryFileData*>::const_iterator it = s_MemoryFiles.begin(); it != s_MemoryFiles.end(); ++it)
- {
- if ((*it)->handle == possibleMemoryFile)
- return true;
- }
- return false;
- }
- static MemoryFileData* FindMemoryFile(void* possibleMemoryFile)
- {
- for (il2cpp::utils::dynamic_array<MemoryFileData*>::iterator it = s_MemoryFiles.begin(); it != s_MemoryFiles.end(); ++it)
- {
- if ((*it)->handle == possibleMemoryFile)
- {
- return *it;
- }
- }
- return NULL;
- }
- static MemoryFileData* FindMemoryFile(const char* mapName)
- {
- for (il2cpp::utils::dynamic_array<MemoryFileData*>::iterator it = s_MemoryFiles.begin(); it != s_MemoryFiles.end(); ++it)
- {
- if (strcmp((*it)->mapName, mapName) == 0)
- {
- return *it;
- }
- }
- return NULL;
- }
- static bool IsMemoryFileView(void* possibleMemoryFile)
- {
- os::FastAutoLock lock(&s_Mutex);
- return std::find(s_MemoryFileViews.begin(), s_MemoryFileViews.end(), possibleMemoryFile) != s_MemoryFileViews.end();
- }
- FileHandle* MemoryMappedFile::Create(FileHandle* file, const char* mapName, int32_t mode, int64_t *capacity, MemoryMappedFileAccess access, int32_t options, MemoryMappedFileError* error)
- {
- if (file == NULL)
- {
- if (mapName != NULL)
- {
- os::FastAutoLock lock(&s_Mutex);
- const MemoryFileData* memoryFileData = FindMemoryFile(mapName);
- if (memoryFileData != NULL)
- {
- file = (FileHandle*)memoryFileData->handle;
- }
- else
- {
- MemoryFileData* memoryFileData = new MemoryFileData(mapName, *capacity);
- s_MemoryFiles.push_back(memoryFileData);
- file = (FileHandle*)memoryFileData->handle;
- }
- }
- }
- return file;
- }
- static MemoryMappedFile::MemoryMappedFileHandle ViewRealFile(FileHandle* mappedFileHandle, int64_t* length, int64_t offset, MemoryMappedFileAccess access, MemoryMappedFileError* error)
- {
- int fileError = 0;
- if (*length == 0)
- {
- *length = os::File::GetLength(mappedFileHandle, &fileError);
- if (fileError != 0)
- {
- if (error != NULL)
- *error = COULD_NOT_MAP_MEMORY;
- return NULL;
- }
- }
- void* buffer = IL2CPP_MALLOC_ZERO((size_t)*length);
- os::File::Seek(mappedFileHandle, offset, 0, &fileError);
- if (fileError != 0)
- {
- IL2CPP_FREE(buffer);
- if (error != NULL)
- *error = COULD_NOT_MAP_MEMORY;
- return NULL;
- }
- int bytesRead = File::Read(mappedFileHandle, (char*)buffer, (int)*length, &fileError);
- if (bytesRead != *length || fileError != 0)
- {
- IL2CPP_FREE(buffer);
- if (error != NULL)
- *error = COULD_NOT_MAP_MEMORY;
- return NULL;
- }
- return buffer;
- }
- static MemoryMappedFile::MemoryMappedFileHandle ViewMemoryFile(void* mappedFileHandle, int64_t* length, int64_t offset, MemoryMappedFileAccess access, MemoryMappedFileError* error)
- {
- os::FastAutoLock lock(&s_Mutex);
- const MemoryFileData* memoryFileData = FindMemoryFile(mappedFileHandle);
- IL2CPP_ASSERT(memoryFileData != NULL);
- if (*length == 0)
- *length = memoryFileData->size;
- if (*length > memoryFileData->size)
- {
- if (error != NULL)
- *error = COULD_NOT_MAP_MEMORY;
- return NULL;
- }
- void* memoryMappedFileView = (uint8_t*)memoryFileData->handle + offset;
- s_MemoryFileViews.push_back(memoryMappedFileView);
- return memoryMappedFileView;
- }
- MemoryMappedFile::MemoryMappedFileHandle MemoryMappedFile::View(FileHandle* mappedFileHandle, int64_t* length, int64_t offset, MemoryMappedFileAccess access, int64_t* actualOffset, MemoryMappedFileError* error)
- {
- IL2CPP_ASSERT(actualOffset != NULL);
- *actualOffset = offset;
- if (IsMemoryFile((void*)mappedFileHandle))
- return ViewMemoryFile((void*)mappedFileHandle, length, offset, access, error);
- else
- return ViewRealFile(mappedFileHandle, length, offset, access, error);
- }
- void MemoryMappedFile::Flush(MemoryMappedFileHandle memoryMappedFileData, int64_t length)
- {
- }
- bool MemoryMappedFile::UnmapView(MemoryMappedFileHandle memoryMappedFileData, int64_t length)
- {
- if (IsMemoryFileView(memoryMappedFileData))
- s_MemoryFileViews.erase_swap_back(&memoryMappedFileData);
- else if (!IsMemoryFile(memoryMappedFileData))
- IL2CPP_FREE(memoryMappedFileData);
- return true;
- }
- bool MemoryMappedFile::Close(FileHandle* file)
- {
- os::FastAutoLock lock(&s_Mutex);
- MemoryFileData* memoryFileData = FindMemoryFile((void*)file);
- if (memoryFileData != NULL)
- {
- delete memoryFileData;
- s_MemoryFiles.erase_swap_back(&memoryFileData);
- }
- return true;
- }
- void MemoryMappedFile::ConfigureHandleInheritability(FileHandle* file, bool inheritability)
- {
- }
- bool MemoryMappedFile::OwnsDuplicatedFileHandle(FileHandle* file)
- {
- return true;
- }
- }
- }
- #endif
|