This class is used for downloading, updating and deleting maps. Storage manages a queue of mwms to be downloaded. Every operation with this queue must be executed on the storage thread. In the current implementation, the storage thread coincides with the main (UI) thread. Downloading of only one mwm at a time is supported, so while the mwm at the top of the queue is being downloaded (or updated by
| 166 | // mwm at the top of the queue is being downloaded (or updated by |
| 167 | // applying a diff file) all other mwms have to wait. |
| 168 | class Storage final : public QueuedCountry::Subscriber |
| 169 | { |
| 170 | public: |
| 171 | using StartDownloadingCallback = std::function<void()>; |
| 172 | using UpdateCallback = std::function<void(storage::CountryId const &, LocalFilePtr const)>; |
| 173 | using DeleteCallback = std::function<bool(storage::CountryId const &, LocalFilePtr const)>; |
| 174 | using CheckUpdatesFunction = std::function<void(storage::CheckUpdatesStatus const &)>; |
| 175 | using ChangeCountryFunction = std::function<void(CountryId const &)>; |
| 176 | using ProgressFunction = std::function<void(CountryId const &, downloader::Progress const &)>; |
| 177 | using DownloadingCountries = ankerl::unordered_dense::map<CountryId, downloader::Progress>; |
| 178 | |
| 179 | private: |
| 180 | /// We support only one simultaneous request at the moment |
| 181 | std::unique_ptr<MapFilesDownloader> m_downloader; |
| 182 | |
| 183 | /// Stores timestamp for update checks |
| 184 | int64_t m_currentVersion = 0; |
| 185 | |
| 186 | CountryTree m_countries; |
| 187 | |
| 188 | std::string m_pendingCountriesBuffer; |
| 189 | int64_t m_pendingCountriesVersion = 0; |
| 190 | bool m_hasPendingCountries = false; |
| 191 | |
| 192 | inline bool IsIdleForCountriesApply() const |
| 193 | { |
| 194 | return m_downloader->GetQueue().IsEmpty() && m_downloadingCountries.empty() && m_diffsBeingApplied.empty(); |
| 195 | } |
| 196 | inline bool IsInitialResourcesDownloadRequired() const |
| 197 | { |
| 198 | std::vector<platform::CountryFile> missing; |
| 199 | return (GetForceDownloadWorlds(missing) == WorldStatus::READY) && !missing.empty(); |
| 200 | } |
| 201 | |
| 202 | inline bool DecodeHex32(std::string_view hex, std::array<uint8_t, 32> & out) |
| 203 | { |
| 204 | if (hex.size() != 64) |
| 205 | return false; |
| 206 | |
| 207 | try |
| 208 | { |
| 209 | boost::algorithm::unhex(hex.begin(), hex.end(), out.begin()); |
| 210 | return true; |
| 211 | } |
| 212 | catch (boost::algorithm::non_hex_input const &) |
| 213 | { |
| 214 | return false; |
| 215 | } |
| 216 | catch (boost::algorithm::not_enough_input const &) |
| 217 | { |
| 218 | return false; |
| 219 | } |
| 220 | } |
| 221 | |
| 222 | void ApplyCountriesInMemory(std::string const & buffer); |
| 223 | void ApplyPendingCountriesIfAny(); |
| 224 | void PersistAndApplyCountries(std::shared_ptr<std::string> buffer, int64_t parsedVersion); |
| 225 | /// \param isEOL is true if no more updates are planned for this map series |
nothing calls this directly
no test coverage detected