diff --git a/Core/MMKV.cpp b/Core/MMKV.cpp index 1440620e..29df7839 100644 --- a/Core/MMKV.cpp +++ b/Core/MMKV.cpp @@ -332,7 +332,7 @@ string MMKV::cryptKey() const { if (m_crypter) { char key[AES_KEY_LEN]; m_crypter->getKey(key); - return string(key, strnlen(key, AES_KEY_LEN)); + return {key, strnlen(key, AES_KEY_LEN)}; } return ""; } @@ -1220,7 +1220,7 @@ static string md5(const basic_string &value) { snprintf(tmp, sizeof(tmp), "%2.2x", ch); strcat(buf, tmp); } - return string(buf); + return {buf}; } static MMKVPath_t encodeFilePath(const string &mmapID) { diff --git a/Core/MemoryFile.cpp b/Core/MemoryFile.cpp index 6feca033..67fbee7f 100644 --- a/Core/MemoryFile.cpp +++ b/Core/MemoryFile.cpp @@ -303,16 +303,106 @@ size_t getPageSize() { #ifndef MMKV_APPLE +static pair createUniqueTempFile(const char *prefix) { + char path[PATH_MAX]; + snprintf(path, PATH_MAX, "%s%s.XXXXX", P_tmpdir, prefix); + + auto fd = mkstemp(path); + if (fd < 0) { + MMKVError("fail to create unique temp file %s, %d(%s)", path, errno, strerror(errno)); + return {"", fd}; + } + return {MMKVPath_t(path), fd}; +} + bool copyFile(const MMKVPath_t &srcPath, const MMKVPath_t &dstPath) { - return false; + auto pair = createUniqueTempFile("MMKV"); + auto tmpFD = pair.second; + auto &tmpPath = pair.first; + if (tmpFD < 0) { + return false; + } + + bool ret = false; + if (copyFileContent(srcPath, tmpFD)) { + MMKVInfo("copyfile [%s] to [%s]", srcPath.c_str(), tmpPath.c_str()); + ret = (::rename(tmpPath.c_str(), dstPath.c_str()) == 0); + if (ret) { + MMKVInfo("copyfile [%s] to [%s] finish.", srcPath.c_str(), dstPath.c_str()); + } else { + MMKVError("fail to rename [%s] to [%s]", tmpPath.c_str(), dstPath.c_str()); + } + } + + ::close(tmpFD); + ::unlink(tmpPath.c_str()); + + return ret; } bool copyFileContent(const MMKVPath_t &srcPath, const MMKVPath_t &dstPath) { - return false; + auto dstFd = open(dstPath.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU); + if (dstFd < 0) { + MMKVError("fail to open [%s], %d(%s)", dstPath.c_str(), errno, strerror(errno)); + return false; + } + auto ret = copyFileContent(srcPath, dstFd); + if (!ret) { + MMKVError("fail to copyfile(): target file %s", dstPath.c_str()); + } else { + MMKVInfo("copy content from %s to [%s] finish", srcPath.c_str(), dstPath.c_str()); + } + ::close(dstFd); + return ret; } bool copyFileContent(const MMKVPath_t &srcPath, MMKVFileHandle_t dstFD) { - return false; + if (dstFD < 0) { + return false; + } + bool ret = false; + char *buffer = nullptr; + auto bufferSize = getPageSize(); + auto srcFd = open(srcPath.c_str(), O_RDONLY, S_IRWXU); + if (srcFd < 0) { + MMKVError("fail to open [%s], %d(%s)", srcPath.c_str(), errno, strerror(errno)); + return false; + } + buffer = (char *)malloc(bufferSize); + if (!buffer) { + MMKVError("fail to malloc size %zu, %d(%s)", bufferSize, errno, strerror(errno)); + goto errorOut; + } + + // the POSIX standard don't have sendfile()/fcopyfile() equivalent, have to do it the hard way + while (true) { + auto sizeRead = read(srcFd, buffer, bufferSize); + if (sizeRead < 0) { + MMKVError("fail to read file [%s], %d(%s)", srcPath.c_str(), errno, strerror(errno)); + goto errorOut; + } + + size_t totalWrite = 0; + do { + auto sizeWrite = write(dstFD, buffer + totalWrite, sizeRead - totalWrite); + if (sizeWrite < 0) { + MMKVError("fail to write fd [%d], %d(%s)", dstFD, errno, strerror(errno)); + goto errorOut; + } + totalWrite += sizeWrite; + } while (totalWrite < sizeRead); + + if (sizeRead < bufferSize) { + break; + } + } + ret = true; + MMKVInfo("copy content from %s to fd[%d] finish", srcPath.c_str(), dstFD); + + errorOut: + free(buffer); + ::close(srcFd); + return ret; } #endif diff --git a/Core/MemoryFile_Android.cpp b/Core/MemoryFile_Android.cpp index c005151d..60bb4b8c 100644 --- a/Core/MemoryFile_Android.cpp +++ b/Core/MemoryFile_Android.cpp @@ -180,7 +180,7 @@ string ASharedMemory_getName(int fd) { MMKVError("fail to get ashmem name:%d, %s", fd, strerror(errno)); return ""; } - return string(name); + return {name}; } } // namespace mmkv diff --git a/Core/MemoryFile_OSX.cpp b/Core/MemoryFile_OSX.cpp index 09702d2b..b1e9a3c8 100644 --- a/Core/MemoryFile_OSX.cpp +++ b/Core/MemoryFile_OSX.cpp @@ -110,9 +110,10 @@ bool copyFileContent(const MMKVPath_t &srcPath, const MMKVPath_t &dstPath) { auto ret = copyFileContent(srcPath, dstFD); if (!ret) { MMKVError("fail to copyfile(): target file %s", dstPath.c_str()); + } else { + MMKVInfo("copy content from %s to fd[%s] finish", srcPath.c_str(), dstPath.c_str()); } ::close(dstFD); - MMKVInfo("copy content from %s to fd[%s] finish", srcPath.c_str(), dstPath.c_str()); return ret; }