Skip to content

Commit b1975b7

Browse files
authored
URLによってはサーバーからテクスチャをダウンロードできないバグを修正 (Synesthesias#157)
* サーバーからテクスチャを取得できないことがあるバグを修正 * コード整理 * コードフォーマット
1 parent 0c4230d commit b1975b7

File tree

1 file changed

+35
-26
lines changed

1 file changed

+35
-26
lines changed

src/dataset/gml_file.cpp

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ namespace plateau::dataset {
3333

3434
/// サーバーモードで使うコンストラクタです。GMLファイルのダウンロードに使う Client を指定します。
3535
GmlFile::GmlFile(const std::string& path, const network::Client& client, int max_lod)
36-
: GmlFile(path){
36+
: GmlFile(path) {
3737
client_ = client;
3838
max_lod_ = max_lod;
3939
}
@@ -78,7 +78,7 @@ namespace plateau::dataset {
7878

7979
auto lods = LodSearcher::searchLodsInFile(fs::u8path(path_));
8080
max_lod_ = lods.getMax();
81-
if(max_lod_ < 0) max_lod_ = 0; // MaxLodが取得できなかった場合のフェイルセーフです。
81+
if (max_lod_ < 0) max_lod_ = 0; // MaxLodが取得できなかった場合のフェイルセーフです。
8282
return max_lod_;
8383
}
8484

@@ -141,17 +141,17 @@ namespace plateau::dataset {
141141
const auto str_begin = str.cbegin();
142142
while (search_pos != str.cend()) {
143143
// ヒントで検索します。
144-
auto hint_matched_pos = str.find(hint, search_pos - str_begin);
144+
const auto hint_matched_pos = str.find(hint, search_pos - str_begin);
145145
// ヒントで検索ヒットしなければ、正規表現でも検索ヒットしません。そのようなヒントが渡されていることが前提です。
146146
if (hint_matched_pos == std::string::npos) return false;
147147
// ヒントが検索ヒットしたので、その周囲の指定数のバイト範囲を正規表現の検索範囲にします。
148-
auto search_start =
148+
const auto search_start =
149149
str_begin + std::max((long long) 0, (long long) hint_matched_pos - search_range_before_hint);
150-
auto search_end = std::min(str.end(),
150+
const auto search_end = std::min(str.end(),
151151
str_begin + (long long) hint_matched_pos + (long long) hint.size() +
152152
search_range_after_hint);
153153
// 正規表現でヒットしたら、その結果を引数 matched に格納して返します。
154-
bool found = std::regex_search(search_start, search_end, matched, regex);
154+
const bool found = std::regex_search(search_start, search_end, matched, regex);
155155
if (found) return true;
156156
// ヒントにはヒットしたけど正規表現にヒットしなかったケースです。検索位置を進めて再度ヒントを検索します。
157157
search_pos = std::min(str.cend(), str_begin + (long long) hint_matched_pos + (long long) hint.size());
@@ -180,7 +180,7 @@ namespace plateau::dataset {
180180
const std::regex& begin_tag_regex, const std::regex& end_tag_regex,
181181
const std::string& str,
182182
const std::string& begin_tag_hint, const std::string& end_tag_hint,
183-
unsigned search_range_before_hint, unsigned search_range_after_hint
183+
const unsigned search_range_before_hint, const unsigned search_range_after_hint
184184
) {
185185
std::set<std::string> found;
186186
std::smatch begin_tag_matched;
@@ -221,7 +221,7 @@ namespace plateau::dataset {
221221
return buffer.str();
222222
}
223223

224-
auto regex_options = std::regex::optimize | std::regex::nosubs;
224+
const auto regex_options = std::regex::optimize | std::regex::nosubs;
225225

226226
/**
227227
* 引数の set の中身を相対パスと解釈し、 setの各要素をコピーします。
@@ -232,8 +232,8 @@ namespace plateau::dataset {
232232
void copyFiles(const std::set<std::string>& path_set, const fs::path& src_base_path,
233233
const fs::path& dest_base_path) {
234234
for (const auto& path: path_set) {
235-
auto src = fs::path(src_base_path).append(path).make_preferred();
236-
auto dest = fs::path(dest_base_path).append(path).make_preferred();
235+
const auto src = fs::path(src_base_path).append(path).make_preferred();
236+
const auto dest = fs::path(dest_base_path).append(path).make_preferred();
237237
if (!fs::exists(src)) {
238238
std::cout << "file not exist : " << src.u8string() << std::endl;
239239
continue;
@@ -249,7 +249,7 @@ namespace plateau::dataset {
249249
void prepareFetch(const fs::path& gml_path, const fs::path& destination_root_path,
250250
fs::path& out_gml_relative_path_from_udx, fs::path& out_destination_udx_path,
251251
fs::path& out_gml_destination_path) {
252-
auto gml_path_str = gml_path.u8string();
252+
const auto gml_path_str = gml_path.u8string();
253253
const auto udx_path_len = gml_path_str.rfind(u8"udx") + 3;
254254
if (udx_path_len == std::string::npos) {
255255
throw std::runtime_error("Invalid gml path. Could not find udx folder");
@@ -265,9 +265,10 @@ namespace plateau::dataset {
265265
fs::create_directories(out_gml_destination_path.parent_path());
266266
}
267267

268-
void fetchLocal(const fs::path& gml_file_path, const fs::path& gml_relative_path_from_udx, const fs::path& destination_udx_path,
268+
void fetchLocal(const fs::path& gml_file_path, const fs::path& gml_relative_path_from_udx,
269+
const fs::path& destination_udx_path,
269270
const fs::path& gml_destination_path, GmlFile& copied_gml_file) {
270-
auto destination_dir = gml_destination_path.parent_path();
271+
const auto destination_dir = gml_destination_path.parent_path();
271272
fs::copy(gml_file_path, gml_destination_path, fs::copy_options::skip_existing);
272273
copied_gml_file.setPath(gml_destination_path.u8string());
273274

@@ -284,9 +285,11 @@ namespace plateau::dataset {
284285
copyFiles(path_to_download, gml_dir_path, app_destination_path);
285286
}
286287

287-
void fetchServer(const fs::path& gml_file_path, const fs::path& gml_relative_path_from_udx, const fs::path& destination_udx_path,
288-
const fs::path& gml_destination_path, GmlFile& copied_gml_file, const network::Client& client) {
289-
auto destination_dir = gml_destination_path.parent_path();
288+
void fetchServer(const fs::path& gml_file_path, const fs::path& gml_relative_path_from_udx,
289+
const fs::path& destination_udx_path,
290+
const fs::path& gml_destination_path, GmlFile& copied_gml_file,
291+
const network::Client& client) {
292+
const auto destination_dir = gml_destination_path.parent_path();
290293
// gmlファイルをダウンロードします。
291294
client.download(destination_dir.u8string(), gml_file_path.u8string());
292295
auto downloaded_path = destination_dir;
@@ -304,15 +307,20 @@ namespace plateau::dataset {
304307
auto path_to_download = image_paths;
305308
path_to_download.insert(codelist_paths.cbegin(), codelist_paths.cend());
306309

307-
auto path_str = gml_file_path.u8string();
308-
auto server_url = path_str.substr(0, path_str.substr(8).find('/') + 8);
309310

310311
for (const auto& relative_path: path_to_download) {
311-
auto full_path = fs::absolute(fs::path(destination_dir) / fs::u8path(relative_path));
312-
auto path = (fs::path(destination_dir) / relative_path).make_preferred();
313-
auto dest_root = destination_udx_path.parent_path().parent_path().make_preferred();
314-
auto path_from_dest_root = fs::relative(path, dest_root).u8string();
315-
auto download_path = (fs::path(server_url) / path_from_dest_root).u8string();
312+
const auto full_path = fs::absolute(fs::path(destination_dir) / fs::u8path(relative_path));
313+
auto download_path = (gml_dir_path / fs::path(relative_path)).lexically_normal().u8string();
314+
std::replace(download_path.begin(), download_path.end(), '\\', '/');
315+
316+
// 上の lexically_normal の副作用で "http(s)://" が "http(s):/" になるので、
317+
// 欠けたスラッシュを1つ追加します。
318+
const auto search = std::string(":/");
319+
const auto pos = download_path.find(search);
320+
const auto len = search.length();
321+
if (pos == 4 || pos == 5) {
322+
download_path.replace(pos, len, "://");
323+
}
316324

317325
client.download(full_path.parent_path().u8string(), download_path);
318326
}
@@ -326,11 +334,12 @@ namespace plateau::dataset {
326334
}
327335

328336
void GmlFile::fetch(const std::string& destination_root_path, GmlFile& copied_gml_file) const {
329-
if(!isValid()) throw std::runtime_error("gml file is invalid.");
337+
if (!isValid()) throw std::runtime_error("gml file is invalid.");
330338
auto gml_relative_path_from_udx = fs::path();
331339
auto destination_udx_path = fs::path();
332340
auto gml_destination_path = fs::path();
333-
prepareFetch(fs::u8path(getPath()), fs::u8path(destination_root_path), gml_relative_path_from_udx, destination_udx_path,
341+
prepareFetch(fs::u8path(getPath()), fs::u8path(destination_root_path), gml_relative_path_from_udx,
342+
destination_udx_path,
334343
gml_destination_path);
335344
if (is_local_) {
336345
// ローカルモード
@@ -358,7 +367,7 @@ namespace plateau::dataset {
358367
}
359368

360369
std::set<std::string> GmlFile::searchAllImagePathsInGML() const {
361-
const auto gml_content = loadFile(fs::u8path(getPath()) );
370+
const auto gml_content = loadFile(fs::u8path(getPath()));
362371
// 開始タグは <app:imageURI> です。ただし、<括弧> の前後に半角スペースがあっても良いものとします。
363372
static const auto begin_tag = std::regex(R"(< *app:imageURI *>)", regex_options);
364373
// 終了タグは </app:imageURI> です。ただし、<括弧> と /(スラッシュ) の前後に半角スペースがあっても良いものとします。

0 commit comments

Comments
 (0)