| 
									
										
										
										
											2019-08-22 20:13:46 +08:00
										 |  |  | //
 | 
					
						
							|  |  |  | //  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"
 | 
					
						
							| 
									
										
										
										
											2020-03-25 20:41:44 +08:00
										 |  |  | #if defined(_MSC_VER)
 | 
					
						
							|  |  |  | #include "Windows.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-08-22 20:13:46 +08:00
										 |  |  | namespace MNN { | 
					
						
							|  |  |  | FileLoader::FileLoader(const char* file) { | 
					
						
							| 
									
										
										
										
											2020-03-25 20:41:44 +08:00
										 |  |  | #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; | 
					
						
							| 
									
										
										
										
											2020-03-25 20:41:44 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | #if _MSC_VER >= 1400
 | 
					
						
							|  |  |  |     if (0 != _wfopen_s(&mFile, wFilename, L"rb")) { | 
					
						
							| 
									
										
										
										
											2020-11-05 16:41:56 +08:00
										 |  |  |         mFile = nullptr; | 
					
						
							| 
									
										
										
										
											2020-03-25 20:41:44 +08:00
										 |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     mFile = _wfopen(wFilename, L"rb"); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2019-08-22 20:13:46 +08:00
										 |  |  |     mFile = fopen(file, "rb"); | 
					
						
							| 
									
										
										
										
											2020-03-25 20:41:44 +08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2021-09-18 15:52:30 +08:00
										 |  |  |     mFilePath = file; | 
					
						
							| 
									
										
										
										
											2019-08-22 20:13:46 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-26 20:40:03 +08:00
										 |  |  | bool FileLoader::write(const char* filePath, std::pair<const void*, size_t> verifyInfo, std::pair<const void*, size_t> cacheInfo) { | 
					
						
							|  |  |  |     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 key
 | 
					
						
							|  |  |  |     auto tsize = fwrite((const char*)verifyInfo.first, 1, verifyInfo.second, f); | 
					
						
							|  |  |  |     if (tsize != verifyInfo.second) { | 
					
						
							| 
									
										
										
										
											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; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     // 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; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-22 20:13:46 +08:00
										 |  |  | 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; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } // namespace MNN
 |