| 487 | } |
| 488 | |
| 489 | bool copyFileContent(const MMKVPath_t &srcPath, MMKVFileHandle_t dstFD, bool needTruncate) { |
| 490 | if (dstFD == INVALID_HANDLE_VALUE) { |
| 491 | return false; |
| 492 | } |
| 493 | bool ret = false; |
| 494 | File srcFile(srcPath, OpenFlag::ReadOnly); |
| 495 | if (!srcFile.isFileValid()) { |
| 496 | return false; |
| 497 | } |
| 498 | auto bufferSize = getPageSize(); |
| 499 | auto buffer = (char *) malloc(bufferSize); |
| 500 | if (!buffer) { |
| 501 | MMKVError("fail to malloc size %zu, %d(%s)", bufferSize, errno, strerror(errno)); |
| 502 | goto errorOut; |
| 503 | } |
| 504 | SetFilePointer(dstFD, 0, 0, FILE_BEGIN); |
| 505 | |
| 506 | // the Win32 platform don't have sendfile()/fcopyfile() equivalent, do it the hard way |
| 507 | while (true) { |
| 508 | DWORD sizeRead = 0; |
| 509 | if (!ReadFile(srcFile.getFd(), buffer, (DWORD) bufferSize, &sizeRead, nullptr)) { |
| 510 | MMKVError("fail to read %s: %d", srcFile.getUTF8Path().c_str(), GetLastError()); |
| 511 | goto errorOut; |
| 512 | } |
| 513 | |
| 514 | DWORD sizeWrite = 0; |
| 515 | if (!WriteFile(dstFD, buffer, sizeRead, &sizeWrite, nullptr)) { |
| 516 | MMKVError("fail to write fd [%d], %d", dstFD, GetLastError()); |
| 517 | goto errorOut; |
| 518 | } |
| 519 | |
| 520 | if (sizeRead < bufferSize) { |
| 521 | break; |
| 522 | } |
| 523 | } |
| 524 | if (needTruncate) { |
| 525 | size_t dstFileSize = 0; |
| 526 | getFileSize(dstFD, dstFileSize); |
| 527 | auto srcFileSize = srcFile.getActualFileSize(); |
| 528 | if ((dstFileSize != srcFileSize) && !ftruncate(dstFD, static_cast<off_t>(srcFileSize))) { |
| 529 | MMKVError("fail to truncate [%d] to size [%zu]", dstFD, srcFileSize); |
| 530 | goto errorOut; |
| 531 | } |
| 532 | } |
| 533 | |
| 534 | ret = true; |
| 535 | MMKVInfo("copy content from %s to fd[%d] finish", srcFile.getUTF8Path().c_str(), dstFD); |
| 536 | |
| 537 | errorOut: |
| 538 | free(buffer); |
| 539 | return ret; |
| 540 | } |
| 541 | |
| 542 | // copy to a temp file then rename it |
| 543 | // this is the best we can do on Win32 |
no test coverage detected