| 1133 | } |
| 1134 | |
| 1135 | bool MMKV::fullWriteback(AESCrypt *newCrypter, bool onlyWhileExpire) { |
| 1136 | if (m_hasFullWriteback) { |
| 1137 | return true; |
| 1138 | } |
| 1139 | if (m_needLoadFromFile) { |
| 1140 | return true; |
| 1141 | } |
| 1142 | if (!isFileValid()) { |
| 1143 | MMKVWarning("[%s] file not valid", m_mmapID.c_str()); |
| 1144 | return false; |
| 1145 | } |
| 1146 | if (isReadOnly()) { |
| 1147 | MMKVWarning("[%s] file readonly", m_mmapID.c_str()); |
| 1148 | return false; |
| 1149 | } |
| 1150 | |
| 1151 | if (mmkv_unlikely(m_enableKeyExpire)) { |
| 1152 | auto expiredCount = filterExpiredKeys(); |
| 1153 | if (onlyWhileExpire && expiredCount == 0) { |
| 1154 | return true; |
| 1155 | } |
| 1156 | } |
| 1157 | |
| 1158 | auto isEmpty = m_crypter ? m_dicCrypt->empty() : m_dic->empty(); |
| 1159 | if (isEmpty) { |
| 1160 | clearAll(); |
| 1161 | return true; |
| 1162 | } |
| 1163 | |
| 1164 | SCOPED_LOCK(m_exclusiveProcessLock); |
| 1165 | auto preparedData = m_crypter ? prepareEncode(*m_dicCrypt) : prepareEncode(*m_dic); |
| 1166 | auto sizeOfDic = preparedData.second; |
| 1167 | if (sizeOfDic > 0) { |
| 1168 | auto fileSize = m_file->getFileSize(); |
| 1169 | if (sizeOfDic + Fixed32Size <= fileSize) { |
| 1170 | return doFullWriteBack(std::move(preparedData), newCrypter); |
| 1171 | } else { |
| 1172 | assert(0); |
| 1173 | assert(newCrypter == nullptr); |
| 1174 | // expandAndWriteBack() will extend file & full rewrite, no need to write back again |
| 1175 | auto newSize = sizeOfDic + Fixed32Size - fileSize; |
| 1176 | return expandAndWriteBack(newSize, std::move(preparedData)); |
| 1177 | } |
| 1178 | } |
| 1179 | return false; |
| 1180 | } |
| 1181 | |
| 1182 | // we don't need to really serialize the dictionary, just reuse what's already in the file |
| 1183 | static void |
nothing calls this directly
no test coverage detected