| 113 | } |
| 114 | |
| 115 | bool MemoryFile::truncate(size_t size, FileLock *fileLock) { |
| 116 | if (m_isMayflyFD) { |
| 117 | openIfNeeded(); |
| 118 | } |
| 119 | if (!m_diskFile.isFileValid()) { |
| 120 | return false; |
| 121 | } |
| 122 | if (size == m_size) { |
| 123 | return true; |
| 124 | } |
| 125 | if (m_readOnly) { |
| 126 | // truncate readonly file not allow |
| 127 | return false; |
| 128 | } |
| 129 | |
| 130 | auto oldSize = m_size; |
| 131 | m_size = size; |
| 132 | // round up to (n * pagesize) |
| 133 | if (m_size < DEFAULT_MMAP_SIZE || (m_size % DEFAULT_MMAP_SIZE != 0)) { |
| 134 | m_size = ((m_size / DEFAULT_MMAP_SIZE) + 1) * DEFAULT_MMAP_SIZE; |
| 135 | } |
| 136 | |
| 137 | // Win32 won't ftruncate a file if there's active file mmapping/handle, we have to unmmap/close ahead |
| 138 | bool needMMapOnFailure = false; |
| 139 | if (m_ptr) { |
| 140 | // if we have a valid file mapping before, we should restore it regardless |
| 141 | needMMapOnFailure = true; |
| 142 | if (!UnmapViewOfFile(m_ptr)) { |
| 143 | MMKVError("fail to munmap [%s], %d", m_diskFile.getUTF8Path().c_str(), GetLastError()); |
| 144 | } |
| 145 | m_ptr = nullptr; |
| 146 | } |
| 147 | if (m_fileMapping) { |
| 148 | CloseHandle(m_fileMapping); |
| 149 | m_fileMapping = nullptr; |
| 150 | } |
| 151 | |
| 152 | if (!ftruncate(m_diskFile.getFd(), m_size)) { |
| 153 | MMKVError("fail to truncate [%s] to size %zu", m_diskFile.getUTF8Path().c_str(), m_size); |
| 154 | m_size = oldSize; |
| 155 | if (needMMapOnFailure) { |
| 156 | mmapOrCleanup(fileLock); |
| 157 | } |
| 158 | return false; |
| 159 | } |
| 160 | if (m_size > oldSize) { |
| 161 | if (!zeroFillFile(m_diskFile.getFd(), oldSize, m_size - oldSize)) { |
| 162 | MMKVError("fail to zeroFile [%s] to size %zu", m_diskFile.getUTF8Path().c_str(), m_size); |
| 163 | m_size = oldSize; |
| 164 | if (needMMapOnFailure) { |
| 165 | mmapOrCleanup(fileLock); |
| 166 | } |
| 167 | return false; |
| 168 | } |
| 169 | } |
| 170 | |
| 171 | return mmapOrCleanup(fileLock); |
| 172 | } |
nothing calls this directly
no test coverage detected