bool OsmOAuth::LoginUserPassword(string const & login, string const & password, SessionID const & sid) const { map<string, string> const params = { {"username", login}, {"password", password}, {"referer", "/"}, {"commit", "Login"}, {"authenticity_token", sid.m_token} }; HttpClient request(m_baseUrl + "/login"); request.SetBodyData(BuildPostRequest(params), "application/x-www-form-urlencoded") .SetCookies(sid.m_cookies) .SetHandleRedirects(false); if (!request.RunHttpRequest()) MYTHROW(NetworkError, ("LoginUserPassword Network error while connecting to", request.UrlRequested())); // At the moment, automatic redirects handling is buggy on Androids < 4.4. // set_handle_redirects(false) works only for Android code, iOS one (and curl) still automatically follow all redirects. if (request.ErrorCode() != HTTP::OK && request.ErrorCode() != HTTP::Found) MYTHROW(LoginUserPasswordServerError, (DebugPrint(request))); // Not redirected page is a 100% signal that login and/or password are invalid. if (!request.WasRedirected()) return false; // Check if we were redirected to some 3rd party site. if (request.UrlReceived().find(m_baseUrl) != 0) MYTHROW(UnexpectedRedirect, (DebugPrint(request))); // m_baseUrl + "/login" means login and/or password are invalid. return request.ServerResponse().find("/login") == string::npos; }
uint64_t FileData::Size() const { #ifdef OMIM_OS_TIZEN Tizen::Io::FileAttributes attr; result const error = Tizen::Io::File::GetAttributes(m_FileName.c_str(), attr); if (IsFailed(error)) MYTHROW(Reader::SizeException, (m_FileName, m_Op, error)); return attr.GetFileSize(); #else int64_t const pos = ftell64(m_File); if (pos == INVALID_POS) MYTHROW(Reader::SizeException, (GetErrorProlog(), pos)); if (fseek64(m_File, 0, SEEK_END)) MYTHROW(Reader::SizeException, (GetErrorProlog())); int64_t const size = ftell64(m_File); if (size == INVALID_POS) MYTHROW(Reader::SizeException, (GetErrorProlog(), size)); if (fseek64(m_File, pos, SEEK_SET)) MYTHROW(Reader::SizeException, (GetErrorProlog(), pos)); ASSERT_GREATER_OR_EQUAL(size, 0, ()); return static_cast<uint64_t>(size); #endif }
// Fakes a buttons press to automatically accept requested permissions. string OsmOAuth::SendAuthRequest(string const & requestTokenKey, SessionID const & sid) const { map<string, string> const params = { {"oauth_token", requestTokenKey}, {"oauth_callback", ""}, {"authenticity_token", sid.m_token}, {"allow_read_prefs", "yes"}, {"allow_write_api", "yes"}, {"allow_write_gpx", "yes"}, {"allow_write_notes", "yes"}, {"commit", "Save changes"} }; HttpClient request(m_baseUrl + "/oauth/authorize"); request.SetBodyData(BuildPostRequest(params), "application/x-www-form-urlencoded") .SetCookies(sid.m_cookies) .SetHandleRedirects(false); if (!request.RunHttpRequest()) MYTHROW(NetworkError, ("SendAuthRequest Network error while connecting to", request.UrlRequested())); string const callbackURL = request.UrlReceived(); string const vKey = "oauth_verifier="; auto const pos = callbackURL.find(vKey); if (pos == string::npos) MYTHROW(SendAuthRequestError, ("oauth_verifier is not found", DebugPrint(request))); auto const end = callbackURL.find("&", pos); return callbackURL.substr(pos + vKey.length(), end == string::npos ? end : end - pos - vKey.length()); }
MappedFile::Handle MappedFile::Map(uint64_t offset, uint64_t size, string const & tag) const { #ifdef OMIM_OS_WINDOWS SYSTEM_INFO sysInfo; memset(&sysInfo, 0, sizeof(sysInfo)); GetSystemInfo(&sysInfo); long const align = sysInfo.dwAllocationGranularity; #else long const align = sysconf(_SC_PAGE_SIZE); #endif uint64_t const alignedOffset = (offset / align) * align; ASSERT_LESS_OR_EQUAL(alignedOffset, offset, ()); uint64_t const length = size + (offset - alignedOffset); ASSERT_GREATER_OR_EQUAL(length, size, ()); #ifdef OMIM_OS_WINDOWS void * pMap = MapViewOfFile(m_hMapping, FILE_MAP_READ, alignedOffset >> (sizeof(DWORD) * 8), DWORD(alignedOffset), length); if (pMap == NULL) MYTHROW(Reader::OpenException, ("Can't map section:", tag, "with [offset, size]:", offset, size, "win last error:", GetLastError())); #else void * pMap = mmap(0, length, PROT_READ, MAP_SHARED, m_fd, alignedOffset); if (pMap == MAP_FAILED) MYTHROW(Reader::OpenException, ("Can't map section:", tag, "with [offset, size]:", offset, size, "errno:", strerror(errno))); #endif char const * data = reinterpret_cast<char const *>(pMap); char const * d = data + (offset - alignedOffset); return Handle(d, data, size, length); }
void OsmOAuth::LogoutUser(SessionID const & sid) const { HttpClient request(m_baseUrl + "/logout"); request.SetCookies(sid.m_cookies); if (!request.RunHttpRequest()) MYTHROW(NetworkError, ("LogoutUser Network error while connecting to", request.UrlRequested())); if (request.ErrorCode() != HTTP::OK) MYTHROW(LogoutUserError, (DebugPrint(request))); }
FeatureID MigrateWayOrRelatonFeatureIndex( osm::Editor::ForEachFeaturesNearByFn & forEach, XMLFeature const & xml, FeatureStatus const /* Unused for now (we don't create/delete area features)*/, GenerateIDFn const & /*Unused for the same reason*/) { boost::optional<FeatureID> fid; auto bestScore = 0.6; // initial score is used as a threshold. auto geometry = xml.GetGeometry(); auto count = 0; if (geometry.empty()) MYTHROW(MigrationError, ("Feature has invalid geometry", xml)); // This can be any point on a feature. auto const someFeaturePoint = geometry[0]; forEach( [&fid, &geometry, &count, &bestScore](FeatureType & ft) { if (ft.GetFeatureType() != feature::GEOM_AREA) return; ++count; auto ftGeometry = ft.GetTriangesAsPoints(FeatureType::BEST_GEOMETRY); double score = 0.0; try { score = matcher::ScoreTriangulatedGeometries(geometry, ftGeometry); } catch (matcher::NotAPolygonException & ex) { // Support migration for old application versions. // TODO(a): To remove it when version 8.0.x will no longer be supported. base::SortUnique(geometry); base::SortUnique(ftGeometry); score = matcher::ScoreTriangulatedGeometriesByPoints(geometry, ftGeometry); } if (score > bestScore) { bestScore = score; fid = ft.GetID(); } }, someFeaturePoint); if (count == 0) MYTHROW(MigrationError, ("No ways returned for point", someFeaturePoint)); if (!fid) { MYTHROW(MigrationError, ("None of returned ways suffice. Possibly, the feature has been deleted.")); } return fid.get(); }
OsmOAuth::Response OsmOAuth::DirectRequest(string const & method, bool api) const { string const url = api ? m_apiUrl + kApiVersion + method : m_baseUrl + method; HttpClient request(url); if (!request.RunHttpRequest()) MYTHROW(NetworkError, ("DirectRequest Network error while connecting to", url)); if (request.WasRedirected()) MYTHROW(UnexpectedRedirect, ("Redirected to", request.UrlReceived(), "from", url)); return Response(request.ErrorCode(), request.ServerResponse()); }
void FileData::Flush() { #ifdef OMIM_OS_TIZEN result const error = m_File->Flush(); if (IsFailed(error)) MYTHROW(Writer::WriteException, (m_FileName, m_Op, error)); #else if (fflush(m_File)) MYTHROW(Writer::WriteException, (GetErrorProlog())); #endif }
void FileData::Write(void const * p, size_t size) { #ifdef OMIM_OS_TIZEN result const error = m_File->Write(p, size); if (IsFailed(error)) MYTHROW(Writer::WriteException, (m_FileName, m_Op, error, size)); #else size_t const bytesWritten = fwrite(p, 1, size, m_File); if (bytesWritten != size || ferror(m_File)) MYTHROW(Writer::WriteException, (GetErrorProlog(), bytesWritten, size)); #endif }
void FileData::Seek(uint64_t pos) { ASSERT_NOT_EQUAL(m_Op, OP_APPEND, (m_FileName, m_Op, pos)); #ifdef OMIM_OS_TIZEN result const error = m_File->Seek(Tizen::Io::FILESEEKPOSITION_BEGIN, pos); if (IsFailed(error)) MYTHROW(Writer::SeekException, (m_FileName, m_Op, error, pos)); #else if (fseek64(m_File, pos, SEEK_SET)) MYTHROW(Writer::SeekException, (GetErrorProlog(), pos)); #endif }
explicit Json(char const * s) { json_error_t jsonError; m_handle.AttachNew(json_loads(s, 0, &jsonError)); if (!m_handle) MYTHROW(Exception, (jsonError.line, jsonError.text)); }
FilesContainerR::TReader FilesContainerR::GetReader(Tag const & tag) const { Info const * p = GetInfo(tag); if (!p) MYTHROW(Reader::OpenException, ("Can't find section:", GetFileName(), tag)); return m_source.SubReader(p->m_offset, p->m_size); }
// static void Serdes::DeserializeInfo(std::vector<int8_t> const & bytes, Info & result) { MemReader reader(bytes.data(), bytes.size()); NonOwningReaderSource source(reader); auto version = static_cast<int8_t>(Version::Unknown); ReadPrimitiveFromSource(source, version); if (version == static_cast<int8_t>(Version::V0)) { try { // TODO: Use temporary object InfoV0 and implement method to convert it to Info, // TODO: when InfoV1 will be implemented. coding::DeserializerJson des(source); des(result); } catch (base::Json::Exception & ex) { LOG(LERROR, ("Cannot deserialize eye file. Exception:", ex.Msg(), "Version:", version, "File content:", std::string(bytes.begin(), bytes.end()))); } return; } MYTHROW(UnknownVersion, ("Unknown data version:", static_cast<int>(version))); }
// Opens a login page and extract a cookie and a secret token. OsmOAuth::SessionID OsmOAuth::FetchSessionId(string const & subUrl) const { string const url = m_baseUrl + subUrl + "?cookie_test=true"; HttpClient request(url); if (!request.RunHttpRequest()) MYTHROW(NetworkError, ("FetchSessionId Network error while connecting to", url)); if (request.WasRedirected()) MYTHROW(UnexpectedRedirect, ("Redirected to", request.UrlReceived(), "from", url)); if (request.ErrorCode() != HTTP::OK) MYTHROW(FetchSessionIdError, (DebugPrint(request))); SessionID const sid = { request.CombinedCookies(), FindAuthenticityToken(request.ServerResponse()) }; if (sid.m_cookies.empty() || sid.m_token.empty()) MYTHROW(FetchSessionIdError, ("Cookies and/or token are empty for request", DebugPrint(request))); return sid; }
FeatureID MigrateNodeFeatureIndex(osm::Editor::ForEachFeaturesNearByFn & forEach, XMLFeature const & xml, FeatureStatus const featureStatus, GenerateIDFn const & generateID) { if (featureStatus == FeatureStatus::Created) return generateID(); FeatureID fid; auto count = 0; forEach( [&fid, &count](FeatureType const & ft) { if (ft.GetFeatureType() != feature::GEOM_POINT) return; // TODO(mgsergio): Check that ft and xml correspond to the same feature. fid = ft.GetID(); ++count; }, MercatorBounds::FromLatLon(xml.GetCenter())); if (count == 0) MYTHROW(MigrationError, ("No pointed features returned.")); if (count > 1) { LOG(LWARNING, (count, "features returned for point", MercatorBounds::FromLatLon(xml.GetCenter()))); } return fid; }
uint64_t FileData::Pos() const { #ifdef OMIM_OS_TIZEN int const pos = m_File->Tell(); result const error = GetLastResult(); if (IsFailed(error)) MYTHROW(Writer::PosException, (m_FileName, m_Op, error, pos)); return pos; #else int64_t const pos = ftell64(m_File); if (pos == INVALID_POS) MYTHROW(Writer::PosException, (GetErrorProlog(), pos)); ASSERT_GREATER_OR_EQUAL(pos, 0, ()); return static_cast<uint64_t>(pos); #endif }
TRequestToken OsmOAuth::FetchRequestToken() const { OAuth::Consumer const consumer(m_consumerKeySecret.first, m_consumerKeySecret.second); OAuth::Client oauth(&consumer); string const requestTokenUrl = m_baseUrl + "/oauth/request_token"; string const requestTokenQuery = oauth.getURLQueryString(OAuth::Http::Get, requestTokenUrl + "?oauth_callback=oob"); HttpClient request(requestTokenUrl + "?" + requestTokenQuery); if (!request.RunHttpRequest()) MYTHROW(NetworkError, ("FetchRequestToken Network error while connecting to", request.UrlRequested())); if (request.ErrorCode() != HTTP::OK) MYTHROW(FetchRequestTokenServerError, (DebugPrint(request))); if (request.WasRedirected()) MYTHROW(UnexpectedRedirect, ("Redirected to", request.UrlReceived(), "from", request.UrlRequested())); // Throws std::runtime_error. OAuth::Token const reqToken = OAuth::Token::extract(request.ServerResponse()); return { reqToken.key(), reqToken.secret() }; }
std::vector<uint8_t> ReadRawData(ReaderSource<FileReader> & src) { uint64_t const size = ReadPrimitiveFromSource<uint64_t>(src); if (src.Size() < size) MYTHROW(Reader::SizeException, (src.Pos(), size)); std::vector<uint8_t> bytes(size); src.Read(bytes.data(), bytes.size()); return bytes; }
pair<uint64_t, uint64_t> FilesContainerR::GetAbsoluteOffsetAndSize(Tag const & tag) const { Info const * p = GetInfo(tag); if (!p) MYTHROW(Reader::OpenException, ("Can't find section:", GetFileName(), tag)); auto reader = dynamic_cast<FileReader const *>(m_source.GetPtr()); uint64_t const offset = reader ? reader->GetOffset() : 0; return make_pair(offset + p->m_offset, p->m_size); }
void FileData::Read(uint64_t pos, void * p, size_t size) { #ifdef OMIM_OS_TIZEN result error = m_File->Seek(Tizen::Io::FILESEEKPOSITION_BEGIN, pos); if (IsFailed(error)) MYTHROW(Reader::ReadException, (error, pos)); int const bytesRead = m_File->Read(p, size); error = GetLastResult(); if (static_cast<size_t>(bytesRead) != size || IsFailed(error)) MYTHROW(Reader::ReadException, (m_FileName, m_Op, error, bytesRead, pos, size)); #else if (fseek64(m_File, pos, SEEK_SET)) MYTHROW(Reader::ReadException, (GetErrorProlog(), pos)); size_t const bytesRead = fread(p, 1, size, m_File); if (bytesRead != size || ferror(m_File)) MYTHROW(Reader::ReadException, (GetErrorProlog(), bytesRead, pos, size)); #endif }
TKeySecret OsmOAuth::FinishAuthorization(TRequestToken const & requestToken, string const & verifier) const { OAuth::Consumer const consumer(m_consumerKeySecret.first, m_consumerKeySecret.second); OAuth::Token const reqToken(requestToken.first, requestToken.second, verifier); OAuth::Client oauth(&consumer, &reqToken); string const accessTokenUrl = m_baseUrl + "/oauth/access_token"; string const queryString = oauth.getURLQueryString(OAuth::Http::Get, accessTokenUrl, "", true); HttpClient request(accessTokenUrl + "?" + queryString); if (!request.RunHttpRequest()) MYTHROW(NetworkError, ("FinishAuthorization Network error while connecting to", request.UrlRequested())); if (request.ErrorCode() != HTTP::OK) MYTHROW(FinishAuthorizationServerError, (DebugPrint(request))); if (request.WasRedirected()) MYTHROW(UnexpectedRedirect, ("Redirected to", request.UrlReceived(), "from", request.UrlRequested())); OAuth::KeyValuePairs const responseData = OAuth::ParseKeyValuePairs(request.ServerResponse()); // Throws std::runtime_error. OAuth::Token const accessToken = OAuth::Token::extract(responseData); return { accessToken.key(), accessToken.secret() }; }
void AssertPosAndSize(uint64_t pos, uint64_t size) const { if (WithExceptions) { if (!GoodPosAndSize(pos, size)) MYTHROW(Reader::SizeException, (pos, size, Size())); } else { ASSERT(GoodPosAndSize(pos, size), (pos, size, Size())); } }
void FileData::Truncate(uint64_t sz) { #ifdef OMIM_OS_WINDOWS int const res = _chsize(fileno(m_File), sz); #elif defined OMIM_OS_TIZEN result res = m_File->Truncate(sz); #else int const res = ftruncate(fileno(m_File), sz); #endif if (res) MYTHROW(Writer::WriteException, (GetErrorProlog(), sz)); }
bool OsmOAuth::LoginSocial(string const & callbackPart, string const & socialToken, SessionID const & sid) const { string const url = m_baseUrl + callbackPart + socialToken; HttpClient request(url); request.SetCookies(sid.m_cookies) .SetHandleRedirects(false); if (!request.RunHttpRequest()) MYTHROW(NetworkError, ("LoginSocial Network error while connecting to", request.UrlRequested())); if (request.ErrorCode() != HTTP::OK && request.ErrorCode() != HTTP::Found) MYTHROW(LoginSocialServerError, (DebugPrint(request))); // Not redirected page is a 100% signal that social login has failed. if (!request.WasRedirected()) return false; // Check if we were redirected to some 3rd party site. if (request.UrlReceived().find(m_baseUrl) != 0) MYTHROW(UnexpectedRedirect, (DebugPrint(request))); // m_baseUrl + "/login" means login and/or password are invalid. return request.ServerResponse().find("/login") == string::npos; }
OsmOAuth::Response OsmOAuth::Request(string const & method, string const & httpMethod, string const & body) const { if (!IsValid(m_tokenKeySecret)) MYTHROW(InvalidKeySecret, ("User token (key and secret) are empty.")); OAuth::Consumer const consumer(m_consumerKeySecret.first, m_consumerKeySecret.second); OAuth::Token const oatoken(m_tokenKeySecret.first, m_tokenKeySecret.second); OAuth::Client oauth(&consumer, &oatoken); OAuth::Http::RequestType reqType; if (httpMethod == "GET") reqType = OAuth::Http::Get; else if (httpMethod == "POST") reqType = OAuth::Http::Post; else if (httpMethod == "PUT") reqType = OAuth::Http::Put; else if (httpMethod == "DELETE") reqType = OAuth::Http::Delete; else MYTHROW(UnsupportedApiRequestMethod, ("Unsupported OSM API request method", httpMethod)); string url = m_apiUrl + kApiVersion + method; string const query = oauth.getURLQueryString(reqType, url); auto const qPos = url.find('?'); if (qPos != string::npos) url = url.substr(0, qPos); HttpClient request(url + "?" + query); if (httpMethod != "GET") request.SetBodyData(body, "application/xml", httpMethod); if (!request.RunHttpRequest()) MYTHROW(NetworkError, ("Request Network error while connecting to", url)); if (request.WasRedirected()) MYTHROW(UnexpectedRedirect, ("Redirected to", request.UrlReceived(), "from", url)); return Response(request.ErrorCode(), request.ServerResponse()); }
bool OsmOAuth::ResetPassword(string const & email) const { string const kForgotPasswordUrlPart = "/user/forgot-password"; SessionID const sid = FetchSessionId(kForgotPasswordUrlPart); map<string, string> const params = { {"user[email]", email}, {"authenticity_token", sid.m_token}, {"commit", "Reset password"} }; HttpClient request(m_baseUrl + kForgotPasswordUrlPart); request.SetBodyData(BuildPostRequest(params), "application/x-www-form-urlencoded"); request.SetCookies(sid.m_cookies); if (!request.RunHttpRequest()) MYTHROW(NetworkError, ("ResetPassword Network error while connecting to", request.UrlRequested())); if (request.ErrorCode() != HTTP::OK) MYTHROW(ResetPasswordServerError, (DebugPrint(request))); if (request.WasRedirected() && request.UrlReceived().find(m_baseUrl) != string::npos) return true; return false; }
FeatureID MigrateFeatureIndex(osm::Editor::ForEachFeaturesNearByFn & forEach, XMLFeature const & xml, FeatureStatus const featureStatus, GenerateIDFn const & generateID) { switch (xml.GetType()) { case XMLFeature::Type::Unknown: MYTHROW(MigrationError, ("Migration for XMLFeature::Type::Unknown is not possible")); case XMLFeature::Type::Node: return MigrateNodeFeatureIndex(forEach, xml, featureStatus, generateID); case XMLFeature::Type::Way: case XMLFeature::Type::Relation: return MigrateWayOrRelatonFeatureIndex(forEach, xml, featureStatus, generateID); } UNREACHABLE(); }
void FixedDstSizeCodeToString(FixedSizeCoderT coder, SrcCharT * pSrc, size_t srcSize, string & dst) { dst.resize(1024); while (true) { size_t dstUsed = coder(pSrc, srcSize, &dst[0], dst.size()); if (dstUsed != -1) { dst.resize(dstUsed); return; } else { // Double dst string size. try { dst.resize(dst.size() * 2); } catch (std::exception & e) { dst.clear(); MYTHROW(DstOutOfMemoryStringCodingException, (e.what())); } } } }
// todo(@m) Factor out to geojson.hpp? Add geojson to myjansson? bool Hierarchy::Entry::DeserializeFromJSONImpl(json_t * const root, string const & jsonStr, ParsingStats & stats) { if (!json_is_object(root)) { ++stats.m_badJsons; MYTHROW(base::Json::Exception, ("Not a json object.")); } json_t * properties = nullptr; FromJSONObject(root, "properties", properties); json_t * address = nullptr; FromJSONObject(properties, "address", address); bool hasDuplicateAddress = false; for (size_t i = 0; i < static_cast<size_t>(Type::Count); ++i) { Type const type = static_cast<Type>(i); string const & levelKey = ToString(type); json_t * levelJson = nullptr; FromJSONObjectOptionalField(address, levelKey, levelJson); if (!levelJson) continue; if (base::JSONIsNull(levelJson)) return false; string levelValue; FromJSON(levelJson, levelValue); if (levelValue.empty()) continue; if (!m_address[i].empty()) { LOG(LDEBUG, ("Duplicate address field", type, "when parsing", jsonStr)); hasDuplicateAddress = true; } search::NormalizeAndTokenizeAsUtf8(levelValue, m_address[i]); if (!m_address[i].empty()) m_type = static_cast<Type>(i); } auto const & subregion = m_address[static_cast<size_t>(Type::Subregion)]; auto const & locality = m_address[static_cast<size_t>(Type::Locality)]; if (m_type == Type::Street && locality.empty() && subregion.empty() /* if locality detection fail */) { ++stats.m_noLocalityStreets; return false; } if (m_type == Type::Building && locality.empty() && subregion.empty() /* if locality detection fail */) { ++stats.m_noLocalityBuildings; return false; } m_nameTokens.clear(); FromJSONObjectOptionalField(properties, "name", m_name); search::NormalizeAndTokenizeAsUtf8(m_name, m_nameTokens); if (m_name.empty()) ++stats.m_emptyNames; if (hasDuplicateAddress) ++stats.m_duplicateAddresses; if (m_type == Type::Count) { LOG(LDEBUG, ("No address in an hierarchy entry:", jsonStr)); ++stats.m_emptyAddresses; } else if (m_nameTokens != m_address[static_cast<size_t>(m_type)]) { ++stats.m_mismatchedNames; } return true; }
ModelReader * Platform::GetReader(string const & file, string const & searchScope) const { string const ext = my::GetFileExtension(file); ASSERT(!ext.empty(), ()); uint32_t const logPageSize = (ext == DATA_FILE_EXTENSION) ? READER_CHUNK_LOG_SIZE : 10; uint32_t const logPageCount = (ext == DATA_FILE_EXTENSION) ? READER_CHUNK_LOG_COUNT : 4; SourceT sources[SOURCE_COUNT]; size_t n = 0; if (searchScope.empty()) { // Default behaviour - use predefined scope for resource files and writable path for all others. if (IsResource(file, ext)) n = GetSearchSources(file, m_androidDefResScope, sources); else { // Add source for map files and other dynamic stored data. sources[n++] = WRITABLE_PATH; sources[n++] = FULL_PATH; } } else { // Use passed scope as client wishes. n = GetSearchSources(file, searchScope, sources); } #ifdef DEBUG DbgLogger logger(file); #endif for (size_t i = 0; i < n; ++i) { #ifdef DEBUG logger.SetSource(sources[i]); #endif switch (sources[i]) { case EXTERNAL_RESOURCE: for (size_t j = 0; j < m_extResFiles.size(); ++j) { try { return new ZipFileReader(m_extResFiles[j], file, logPageSize, logPageCount); } catch (Reader::OpenException const &) { } } break; case WRITABLE_PATH: { string const path = m_writableDir + file; if (IsFileExistsByFullPath(path)) return new FileReader(path, logPageSize, logPageCount); break; } case SETTINGS_PATH: { string const path = m_settingsDir + file; if (IsFileExistsByFullPath(path)) return new FileReader(path, logPageSize, logPageCount); break; } case FULL_PATH: if (IsFileExistsByFullPath(file)) return new FileReader(file, logPageSize, logPageCount); break; case RESOURCE: ASSERT_EQUAL(file.find("assets/"), string::npos, ()); try { return new ZipFileReader(m_resourcesDir, "assets/" + file, logPageSize, logPageCount); } catch (Reader::OpenException const &) { } break; default: CHECK(false, ("Unsupported source:", sources[i])); break; } } LOG(LWARNING, ("Can't get reader for:", file)); MYTHROW(FileAbsentException, ("File not found", file)); return 0; }