| 88 | } |
| 89 | |
| 90 | bool copyFile(const MMKVPath_t &srcPath, const MMKVPath_t &dstPath) { |
| 91 | // prepare a temp file for atomic rename, avoid data corruption of sudden crash |
| 92 | NSString *uniqueFileName = [NSString stringWithFormat:@"mmkv_%zu", (size_t) NSDate.timeIntervalSinceReferenceDate]; |
| 93 | NSString *tmpFile = [NSTemporaryDirectory() stringByAppendingPathComponent:uniqueFileName]; |
| 94 | if (copyfile(srcPath.c_str(), tmpFile.UTF8String, nullptr, COPYFILE_UNLINK | COPYFILE_CLONE) != 0) { |
| 95 | MMKVError("fail to copyfile [%s] to [%s], %s", srcPath.c_str(), tmpFile.UTF8String, strerror(errno)); |
| 96 | return false; |
| 97 | } |
| 98 | MMKVInfo("copyfile [%s] to [%s]", srcPath.c_str(), tmpFile.UTF8String); |
| 99 | |
| 100 | if (tryAtomicRename(tmpFile.UTF8String, dstPath.c_str())) { |
| 101 | MMKVInfo("copyfile [%s] to [%s] finish.", srcPath.c_str(), dstPath.c_str()); |
| 102 | return true; |
| 103 | } |
| 104 | |
| 105 | MMKVInfo("rename fail, try copy file content instead."); |
| 106 | auto ret = copyFileContent(tmpFile.UTF8String, dstPath); |
| 107 | |
| 108 | unlink(tmpFile.UTF8String); |
| 109 | return ret; |
| 110 | } |
| 111 | |
| 112 | bool copyFileContent(const MMKVPath_t &srcPath, const MMKVPath_t &dstPath) { |
| 113 | File dstFile(dstPath, OpenFlag::WriteOnly | OpenFlag::Create | OpenFlag::Truncate); |
nothing calls this directly
no test coverage detected