diff options
author | vng <viktor.govako@gmail.com> | 2014-10-08 19:23:23 +0400 |
---|---|---|
committer | Alex Zolotarev <alex@maps.me> | 2015-09-23 02:29:46 +0300 |
commit | 6defa5228a6768d54824460c1582da71371783e1 (patch) | |
tree | 9f31d129dfd787e1e0136b8cd629d1d563f0df04 /storage | |
parent | b7c53102fb0e32ca343a7e782ceb1c2b2a26bf0a (diff) |
[storage] Do download .routing file.
Diffstat (limited to 'storage')
-rw-r--r-- | storage/country.cpp | 64 | ||||
-rw-r--r-- | storage/country.hpp | 30 | ||||
-rw-r--r-- | storage/storage.cpp | 179 | ||||
-rw-r--r-- | storage/storage.hpp | 55 | ||||
-rw-r--r-- | storage/storage_tests/storage_tests.cpp | 6 |
5 files changed, 235 insertions, 99 deletions
diff --git a/storage/country.cpp b/storage/country.cpp index 2fe9f84300..89a02d7f28 100644 --- a/storage/country.cpp +++ b/storage/country.cpp @@ -10,10 +10,22 @@ namespace storage { -uint32_t CountryFile::GetFileSize() const +string CountryFile::GetFileWithExt(TMapOptions opt) const +{ + switch (opt) + { + case TMapOptions::EMapOnly: return m_fileName + DATA_FILE_EXTENSION; + case TMapOptions::ECarRouting: return m_fileName + DATA_FILE_EXTENSION + ROUTING_FILE_EXTENSION; + } + + ASSERT(false, ()); + return string(); +} + +uint32_t CountryFile::GetFileSize(TMapOptions opt) const { uint64_t size = 0; - if (GetPlatform().GetFileSizeByName(GetFileWithExt(), size)) + if (GetPlatform().GetFileSizeByName(GetFileWithExt(opt), size)) { uint32_t const ret = static_cast<uint32_t>(size); ASSERT_EQUAL ( ret, size, () ); @@ -23,6 +35,18 @@ uint32_t CountryFile::GetFileSize() const return 0; } +uint32_t CountryFile::GetRemoteSize(TMapOptions opt) const +{ + switch (opt) + { + case TMapOptions::EMapOnly: return m_mapSize; + case TMapOptions::ECarRouting: return m_routingSize; + } + + ASSERT(false, ()); + return 0; +} + /* class CountryBoundsCalculator { @@ -51,13 +75,13 @@ m2::RectD Country::Bounds() const } */ -LocalAndRemoteSizeT Country::Size() const +LocalAndRemoteSizeT Country::Size(TMapOptions opt) const { uint64_t localSize = 0, remoteSize = 0; - for (FilesContainerT::const_iterator it = m_files.begin(); it != m_files.end(); ++it) + for (CountryFile const & f : m_files) { - localSize += it->GetFileSize(); - remoteSize += it->m_remoteSize; + localSize += f.GetFileSize(opt); + remoteSize += f.GetRemoteSize(opt); } return LocalAndRemoteSizeT(localSize, remoteSize); } @@ -76,19 +100,22 @@ void LoadGroupImpl(int depth, json_t * group, ToDo & toDo) for (size_t i = 0; i < json_array_size(group); ++i) { json_t * j = json_array_get(group, i); + // name is mandatory char const * name = json_string_value(json_object_get(j, "n")); if (!name) MYTHROW(my::Json::Exception, ("Country name is missing")); - // other fields are optional - char const * flag = json_string_value(json_object_get(j, "c")); + char const * file = json_string_value(json_object_get(j, "f")); // if file is empty, it's the same as the name if (!file) file = name; - json_int_t const size = json_integer_value(json_object_get(j, "s")); - toDo(name, file, flag ? flag : "", size, depth); + char const * flag = json_string_value(json_object_get(j, "c")); + toDo(name, file, flag ? flag : "", + json_integer_value(json_object_get(j, "s")), + json_integer_value(json_object_get(j, "rs")), + depth); json_t * children = json_object_get(j, "g"); if (children) @@ -128,11 +155,11 @@ namespace DoStoreCountries(CountriesContainerT & cont) : m_cont(cont) {} void operator() (string const & name, string const & file, string const & flag, - uint32_t size, int depth) + uint32_t mapSize, uint32_t routingSize, int depth) { Country country(name, flag); - if (size) - country.AddFile(CountryFile(file, size)); + if (mapSize) + country.AddFile(CountryFile(file, mapSize, routingSize)); m_cont.AddAtDepth(depth, country); } }; @@ -146,12 +173,12 @@ namespace DoStoreFile2Info(map<string, CountryInfo> & file2info) : m_file2info(file2info) {} void operator() (string name, string file, string const & flag, - uint32_t size, int) + uint32_t mapSize, uint32_t, int) { if (!flag.empty()) m_lastFlag = flag; - if (size) + if (mapSize) { CountryInfo info; @@ -187,7 +214,7 @@ namespace DoStoreCode2File(multimap<string, string> & code2file) : m_code2file(code2file) {} void operator() (string const &, string const & file, string const & flag, - uint32_t, int) + uint32_t, uint32_t, int) { m_code2file.insert(make_pair(flag, file)); } @@ -240,10 +267,11 @@ void SaveImpl(T const & v, json_t * jParent) if (countriesCount > 0) { CountryFile const & file = v[i].Value().GetFile(); - string const strFile = file.m_fileName; + string const & strFile = file.GetFileWithoutExt(); if (strFile != strName) json_object_set_new(jCountry.get(), "f", json_string(strFile.c_str())); - json_object_set_new(jCountry.get(), "s", json_integer(file.m_remoteSize)); + json_object_set_new(jCountry.get(), "s", json_integer(file.GetRemoteSize(TMapOptions::EMapOnly))); + json_object_set_new(jCountry.get(), "rs", json_integer(file.GetRemoteSize(TMapOptions::ECarRouting))); } if (v[i].SiblingsCount()) diff --git a/storage/country.hpp b/storage/country.hpp index 1faa970995..a62870ed81 100644 --- a/storage/country.hpp +++ b/storage/country.hpp @@ -19,19 +19,29 @@ namespace update { class SizeUpdater; } namespace storage { /// Information about each file for a country - struct CountryFile + class CountryFile { - CountryFile() : m_remoteSize(0) {} - CountryFile(string const & fName, uint32_t remoteSize) - : m_fileName(fName), m_remoteSize(remoteSize) {} + string m_fileName; /// Same as id of country\region. + uint32_t m_mapSize, m_routingSize; - string GetFileWithExt() const { return m_fileName + DATA_FILE_EXTENSION; } - string const & GetFileWithoutExt() const { return m_fileName; } + public: + CountryFile() {} + CountryFile(string const & fName, uint32_t mapSize, uint32_t routingSize) + : m_fileName(fName), m_mapSize(mapSize), m_routingSize(routingSize) + { + } - uint32_t GetFileSize() const; + void AssignSizes(uint32_t mapSize, uint32_t routingSize) + { + m_mapSize = mapSize; + m_routingSize = routingSize; + } - string m_fileName; /// Same as id of country\region. - uint32_t m_remoteSize; + string GetFileWithExt(TMapOptions opt) const; + string const & GetFileWithoutExt() const { return m_fileName; } + + uint32_t GetFileSize(TMapOptions opt) const; + uint32_t GetRemoteSize(TMapOptions opt) const; }; typedef buffer_vector<CountryFile, 1> FilesContainerT; @@ -79,7 +89,7 @@ namespace storage /// @return bounds for downloaded parts of the country or empty rect //m2::RectD Bounds() const; - LocalAndRemoteSizeT Size() const; + LocalAndRemoteSizeT Size(TMapOptions opt) const; }; typedef SimpleTree<Country> CountriesContainerT; diff --git a/storage/storage.cpp b/storage/storage.cpp index 9d605ca37a..c43bc18b7c 100644 --- a/storage/storage.cpp +++ b/storage/storage.cpp @@ -50,6 +50,69 @@ namespace storage } */ + Storage::QueuedCountry::QueuedCountry(Storage const & storage, TIndex const & index, TMapOptions opt) + : m_index(index), m_init(opt), m_left(opt) + { + m_pFile = &(storage.CountryByIndex(index).GetFile()); + m_current = (m_init & TMapOptions::EMapOnly ? TMapOptions::EMapOnly : TMapOptions::ECarRouting); + } + + void Storage::QueuedCountry::AddOptions(TMapOptions opt) + { + TMapOptions arr[] = { TMapOptions::EMapOnly, TMapOptions::ECarRouting }; + for (size_t i = 0; i < ARRAY_SIZE(arr); ++i) + { + if (opt & arr[i] && !(m_init & arr[i])) + { + m_init |= arr[i]; + m_left |= arr[i]; + } + } + } + + bool Storage::QueuedCountry::MoveNextFile() + { + if (m_current == m_left) + return false; + + if (m_current == TMapOptions::EMapOnly) + m_left = m_current = TMapOptions::ECarRouting; + else + m_left = m_current = TMapOptions::EMapOnly; + return true; + } + + uint64_t Storage::QueuedCountry::GetDownloadSize() const + { + return m_pFile->GetRemoteSize(m_current); + } + + LocalAndRemoteSizeT Storage::QueuedCountry::GetFullSize() const + { + LocalAndRemoteSizeT res(0, 0); + TMapOptions arr[] = { TMapOptions::EMapOnly, TMapOptions::ECarRouting }; + for (size_t i = 0; i < ARRAY_SIZE(arr); ++i) + { + if (m_init & arr[i]) + { + res.first += m_pFile->GetFileSize(m_current); + res.second += m_pFile->GetRemoteSize(m_current); + } + } + return res; + } + + string Storage::QueuedCountry::GetFileName() const + { + return m_pFile->GetFileWithExt(m_current); + } + + string Storage::QueuedCountry::GetMapFileName() const + { + return m_pFile->GetFileWithExt(TMapOptions::EMapOnly); + } + + Storage::Storage() : m_currentSlotId(0) { LoadCountriesFile(false); @@ -70,7 +133,6 @@ namespace storage } } - //////////////////////////////////////////////////////////////////////////// void Storage::Init(TUpdateAfterDownload const & updateFn) { m_updateAfterDownload = updateFn; @@ -98,7 +160,7 @@ namespace storage void Storage::GetGroupAndCountry(TIndex const & index, string & group, string & country) const { - string fName = CountryByIndex(index).GetFile().m_fileName; + string fName = CountryByIndex(index).GetFile().GetFileWithoutExt(); CountryInfo::FileName2FullName(fName); CountryInfo::FullName2GroupAndMap(fName, group, country); } @@ -118,26 +180,25 @@ namespace storage return NodeFromIndex(m_countries, index).Value().Flag(); } - string const & Storage::CountryFileName(TIndex const & index) const + string Storage::CountryFileName(TIndex const & index, TMapOptions opt) const { - return NodeFromIndex(m_countries, index).Value().GetFile().GetFileWithoutExt(); + return QueuedCountry(*this, index, opt).GetFileName(); } - LocalAndRemoteSizeT Storage::CountrySizeInBytes(TIndex const & index) const + string const & Storage::CountryFileNameWithoutExt(TIndex const & index) const { - return CountryByIndex(index).Size(); + return CountryByIndex(index).GetFile().GetFileWithoutExt(); } - LocalAndRemoteSizeT Storage::CountrySizeInBytesEx(const TIndex & index, const TMapOptions & options) const + LocalAndRemoteSizeT Storage::CountrySizeInBytes(const TIndex & index, TMapOptions opt) const { - ///@TODO for vng - return CountryByIndex(index).Size(); + return QueuedCountry(*this, index, opt).GetFullSize(); } TStatus Storage::CountryStatus(TIndex const & index) const { // first, check if we already downloading this country or have in in the queue - TQueue::const_iterator found = std::find(m_queue.begin(), m_queue.end(), index); + auto found = find(m_queue.begin(), m_queue.end(), index); if (found != m_queue.end()) { if (found == m_queue.begin()) @@ -159,7 +220,7 @@ namespace storage if (res == TStatus::EUnknown) { Country const & c = CountryByIndex(index); - LocalAndRemoteSizeT const size = c.Size(); + LocalAndRemoteSizeT const size = c.Size(TMapOptions::EMapOnly); if (size.first == 0) return TStatus::ENotDownloaded; @@ -175,10 +236,10 @@ namespace storage // Additional check for .ready file. // Use EOnDisk status if it's good, or EOnDiskOutOfDate otherwise. Platform const & pl = GetPlatform(); - string const fName = pl.WritablePathForFile(c.GetFile().GetFileWithExt() + READY_FILE_EXTENSION); + string const fName = c.GetFile().GetFileWithExt(TMapOptions::EMapOnly) + READY_FILE_EXTENSION; uint64_t sz = 0; - if (!pl.GetFileSizeByFullPath(fName, sz) || sz != size.second) + if (!pl.GetFileSizeByFullPath(pl.WritablePathForFile(fName), sz) || sz != size.second) res = TStatus::EOnDiskOutOfDate; } } @@ -188,22 +249,26 @@ namespace storage void Storage::CountryStatusEx(TIndex const & index, TStatus & status, TMapOptions & options) const { - ///@TODO for vng status = CountryStatusEx(index); + + if (status == TStatus::EOnDisk || status == TStatus::EOnDiskOutOfDate) + { + options = TMapOptions::EMapOnly; + + string const fName = QueuedCountry(*this, index, TMapOptions::ECarRouting).GetFileName(); + Platform const & pl = GetPlatform(); + if (pl.IsFileExistsByFullPath(pl.WritablePathForFile(fName))) + options |= TMapOptions::ECarRouting; + } } - void Storage::DownloadCountry(TIndex const & index, TMapOptions const & options) + void Storage::DownloadCountry(TIndex const & index, TMapOptions opt) { -#ifdef DEBUG - if (options & TMapOptions::EMapWithCarRouting) - ASSERT(options & TMapOptions::EMapOnly, ()); -#endif - ///@TODO for vng. Process options // check if we already downloading this country - TQueue::const_iterator found = find(m_queue.begin(), m_queue.end(), index); + auto found = find(m_queue.begin(), m_queue.end(), index); if (found != m_queue.end()) { - // do nothing + found->AddOptions(opt); return; } @@ -212,7 +277,7 @@ namespace storage // remove it from failed list m_failedCountries.erase(index); // add it into the queue - m_queue.push_back(index); + m_queue.push_back(QueuedCountry(*this, index, opt)); // and start download if necessary if (m_queue.size() == 1) @@ -228,33 +293,34 @@ namespace storage void Storage::NotifyStatusChanged(TIndex const & index) { - for (list<CountryObservers>::const_iterator it = m_observers.begin(); it != m_observers.end(); ++it) - it->m_changeCountryFn(index); + for (CountryObservers const & o : m_observers) + o.m_changeCountryFn(index); } void Storage::DownloadNextCountryFromQueue() { if (!m_queue.empty()) { - TIndex const index = m_queue.front(); - Country const & country = CountryByIndex(index); + QueuedCountry & cnt = m_queue.front(); - /// Reset progress before downloading. - /// @todo If we will have more than one file per country, - /// we should initialize progress before calling DownloadNextCountryFromQueue(). m_countryProgress.first = 0; - m_countryProgress.second = country.Size().second; + m_countryProgress.second = cnt.GetFullSize().second; - // send Country name for statistics - m_request.reset(HttpRequest::PostJson(GetPlatform().MetaServerUrl(), - country.GetFile().m_fileName, - bind(&Storage::OnServerListDownloaded, this, _1))); + DownloadNextFile(cnt); // new status for country, "Downloading" - NotifyStatusChanged(index); + NotifyStatusChanged(cnt.GetIndex()); } } + void Storage::DownloadNextFile(QueuedCountry const & cnt) + { + // send Country name for statistics + m_request.reset(HttpRequest::PostJson(GetPlatform().MetaServerUrl(), + cnt.GetFileName(), + bind(&Storage::OnServerListDownloaded, this, _1))); + } + /* m2::RectD Storage::CountryBounds(TIndex const & index) const { @@ -266,7 +332,7 @@ namespace storage bool Storage::DeleteFromDownloader(TIndex const & index) { // check if we already downloading this country - TQueue::iterator found = find(m_queue.begin(), m_queue.end(), index); + auto found = find(m_queue.begin(), m_queue.end(), index); if (found != m_queue.end()) { if (found == m_queue.begin()) @@ -326,7 +392,7 @@ namespace storage void Storage::Unsubscribe(int slotId) { - for (ObserversContT::iterator i = m_observers.begin(); i != m_observers.end(); ++i) + for (auto i = m_observers.begin(); i != m_observers.end(); ++i) { if (i->m_slotId == slotId) { @@ -344,8 +410,8 @@ namespace storage return; } - TIndex const index = m_queue.front(); - m_queue.pop_front(); + QueuedCountry & cnt = m_queue.front(); + TIndex const index = cnt.GetIndex(); if (request.Status() == HttpRequest::EFailed) { @@ -354,12 +420,18 @@ namespace storage } else { - Country const & country = CountryByIndex(index); + if (cnt.MoveNextFile()) + { + DownloadNextFile(cnt); + return; + } // notify framework that downloading is done - m_updateAfterDownload(country.GetFile().GetFileWithExt()); + m_updateAfterDownload(cnt.GetMapFileName(), cnt.GetInitOptions()); } + m_queue.pop_front(); + NotifyStatusChanged(index); m_request.reset(); @@ -368,8 +440,8 @@ namespace storage void Storage::ReportProgress(TIndex const & idx, pair<int64_t, int64_t> const & p) { - for (ObserversContT::const_iterator i = m_observers.begin(); i != m_observers.end(); ++i) - i->m_progressFn(idx, p); + for (CountryObservers const & o : m_observers) + o.m_progressFn(idx, p); } void Storage::OnMapDownloadProgress(HttpRequest & request) @@ -386,7 +458,7 @@ namespace storage p.first += m_countryProgress.first; p.second = m_countryProgress.second; - ReportProgress(m_queue.front(), p); + ReportProgress(m_queue.front().GetIndex(), p); } } @@ -398,17 +470,18 @@ namespace storage return; } - CountryFile const & file = CountryByIndex(m_queue.front()).GetFile(); + QueuedCountry const & cnt = m_queue.front(); vector<string> urls; GetServerListFromRequest(request, urls); // append actual version and file name + string fileName = cnt.GetFileName(); for (size_t i = 0; i < urls.size(); ++i) - urls[i] = GetFileDownloadUrl(urls[i], file.GetFileWithExt()); + urls[i] = GetFileDownloadUrl(urls[i], fileName); - string const fileName = GetPlatform().WritablePathForFile(file.GetFileWithExt() + READY_FILE_EXTENSION); - m_request.reset(HttpRequest::GetFile(urls, fileName, file.m_remoteSize, + string const filePath = GetPlatform().WritablePathForFile(fileName + READY_FILE_EXTENSION); + m_request.reset(HttpRequest::GetFile(urls, filePath, cnt.GetDownloadSize(), bind(&Storage::OnMapDownloadFinished, this, _1), bind(&Storage::OnMapDownloadProgress, this, _1))); ASSERT ( m_request, () ); @@ -423,24 +496,24 @@ namespace storage { Country const & c = node.Value(); if (c.GetFilesCount() > 0) - return (c.GetFile().m_fileName == name); + return (c.GetFile().GetFileWithoutExt() == name); else return false; } TIndex Storage::FindIndexByFile(string const & name) const { - for (unsigned i = 0; i < m_countries.SiblingsCount(); ++i) + for (size_t i = 0; i < m_countries.SiblingsCount(); ++i) { if (IsEqualFileName(m_countries[i], name)) return TIndex(i); - for (unsigned j = 0; j < m_countries[i].SiblingsCount(); ++j) + for (size_t j = 0; j < m_countries[i].SiblingsCount(); ++j) { if (IsEqualFileName(m_countries[i][j], name)) return TIndex(i, j); - for (unsigned k = 0; k < m_countries[i][j].SiblingsCount(); ++k) + for (size_t k = 0; k < m_countries[i][j].SiblingsCount(); ++k) { if (IsEqualFileName(m_countries[i][j][k], name)) return TIndex(i, j, k); diff --git a/storage/storage.hpp b/storage/storage.hpp index 87b2b5838a..7dce7fb8b5 100644 --- a/storage/storage.hpp +++ b/storage/storage.hpp @@ -29,7 +29,31 @@ namespace storage CountriesContainerT m_countries; /// store queue for downloading - typedef list<TIndex> TQueue; + class QueuedCountry + { + TIndex m_index; + CountryFile const * m_pFile; + TMapOptions m_init, m_left, m_current; + + public: + explicit QueuedCountry(TIndex const & index) : m_index(index), m_pFile(0) {} + QueuedCountry(Storage const & storage, TIndex const & index, TMapOptions opt); + + void AddOptions(TMapOptions opt); + bool MoveNextFile(); + + TIndex const & GetIndex() const { return m_index; } + TMapOptions GetInitOptions() const { return m_init; } + + bool operator== (TIndex const & index) const { return (m_index == index); } + + uint64_t GetDownloadSize() const; + LocalAndRemoteSizeT GetFullSize() const; + string GetFileName() const; + string GetMapFileName() const; + }; + + typedef list<QueuedCountry> TQueue; TQueue m_queue; /// stores countries which download has failed recently @@ -60,7 +84,7 @@ namespace storage /// @name Communicate with Framework //@{ - typedef function<void (string const &)> TUpdateAfterDownload; + typedef function<void (string const &, TMapOptions)> TUpdateAfterDownload; TUpdateAfterDownload m_updateAfterDownload; //@} @@ -70,26 +94,23 @@ namespace storage void ReportProgress(TIndex const & index, pair<int64_t, int64_t> const & p); - public: - Storage(); - - void Init(TUpdateAfterDownload const & updateFn); - - /// @name Called from DownloadManager + /// @name //@{ void OnServerListDownloaded(downloader::HttpRequest & request); void OnMapDownloadFinished(downloader::HttpRequest & request); void OnMapDownloadProgress(downloader::HttpRequest & request); + void DownloadNextFile(QueuedCountry const & cnt); //@} - /// @name Current impl supports only one observer - //@{ + public: + Storage(); + + void Init(TUpdateAfterDownload const & updateFn); /// @return unique identifier that should be used with Unsubscribe function int Subscribe(TChangeCountryFunction const & change, TProgressFunction const & progress); void Unsubscribe(int slotId); - //@} Country const & CountryByIndex(TIndex const & index) const; TIndex FindIndexByFile(string const & name) const; @@ -98,18 +119,20 @@ namespace storage size_t CountriesCount(TIndex const & index) const; string const & CountryName(TIndex const & index) const; string const & CountryFlag(TIndex const & index) const; - /// @return Country file name without extension. - string const & CountryFileName(TIndex const & index) const; - LocalAndRemoteSizeT CountrySizeInBytes(TIndex const & index) const; - LocalAndRemoteSizeT CountrySizeInBytesEx(TIndex const & index, TMapOptions const & options) const; + + string CountryFileName(TIndex const & index, TMapOptions opt) const; + string const & CountryFileNameWithoutExt(TIndex const & index) const; + LocalAndRemoteSizeT CountrySizeInBytes(TIndex const & index, TMapOptions opt) const; + /// Fast version, doesn't check if country is out of date TStatus CountryStatus(TIndex const & index) const; /// Slow version, but checks if country is out of date TStatus CountryStatusEx(TIndex const & index) const; void CountryStatusEx(TIndex const & index, TStatus & status, TMapOptions & options) const; + //m2::RectD CountryBounds(TIndex const & index) const; - void DownloadCountry(TIndex const & index, TMapOptions const & options); + void DownloadCountry(TIndex const & index, TMapOptions opt); bool DeleteFromDownloader(TIndex const & index); bool IsDownloadInProgress() const; diff --git a/storage/storage_tests/storage_tests.cpp b/storage/storage_tests/storage_tests.cpp index fbdc6ca64c..15f9e63264 100644 --- a/storage/storage_tests/storage_tests.cpp +++ b/storage/storage_tests/storage_tests.cpp @@ -2,6 +2,8 @@ #include "../storage.hpp" +#include "../../defines.hpp" + using namespace storage; @@ -12,11 +14,11 @@ UNIT_TEST(StorageTest_Smoke) TIndex const i1 = st.FindIndexByFile("USA_Georgia"); TEST(i1.IsValid(), ()); - TEST_EQUAL(st.CountryFileName(i1), "USA_Georgia", ()); + TEST_EQUAL(st.CountryFileName(i1, TMapOptions::EMapOnly), "USA_Georgia" DATA_FILE_EXTENSION, ()); TIndex const i2 = st.FindIndexByFile("Georgia"); TEST(i2.IsValid(), ()); - TEST_EQUAL(st.CountryFileName(i2), "Georgia", ()); + TEST_EQUAL(st.CountryFileName(i2, TMapOptions::ECarRouting), "Georgia" DATA_FILE_EXTENSION ROUTING_FILE_EXTENSION, ()); TEST_NOT_EQUAL(i1, i2, ()); } |