Skip to content

Commit

Permalink
Fix #11
Browse files Browse the repository at this point in the history
* fix: handle empty string to number conversion

* fix: dup artists
  • Loading branch information
pnck authored May 16, 2024
1 parent 95d95af commit 6225b53
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 30 deletions.
8 changes: 4 additions & 4 deletions src/common/helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ namespace
using base_t = std::string;
constexpr decay_string() : base_t() {}
constexpr decay_string(base_t &&str) noexcept : base_t(std::move(str)) {}
operator const char *() const noexcept { return this->data(); }
operator std::string_view() const noexcept { return {this->data(), this->size()}; }
constexpr operator const char *() const noexcept { return this->data(); }
constexpr operator std::string_view() const noexcept { return {this->data(), this->size()}; }
};

constexpr decay_string operator""_upper(const char *str, std::size_t len) {
Expand All @@ -40,14 +40,14 @@ namespace
}
return result;
}
/*
#if 0 // string can be implicitly converted to string_view
constexpr decay_string upper(const std::string &s) {
decay_string result;
std::transform(
s.begin(), s.end(), std::back_inserter(result), [](char c) -> char { return (c >= 'a' && c <= 'z') ? c - ('a' - 'A') : c;
}); return result;
}
*/
#endif
constexpr auto upper(std::string_view v) {
return operator""_upper(v.data(), v.size());
}
Expand Down
2 changes: 2 additions & 0 deletions src/common/log.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,4 +165,6 @@ extern const struct _spdlog_init_helper_st {
#define DEBUG_LOG(...) SPDLOG_DEBUG(_forward_strs(__VA_ARGS__))
#define DEBUG_LOG_F(...) SPDLOG_DEBUG(__VA_ARGS__)
#define WARN_LOG(...) SPDLOG_WARN(_forward_strs(__VA_ARGS__))
#define WARN_LOG_F(...) SPDLOG_WARN(__VA_ARGS__)
#define ERROR_LOG(...) SPDLOG_ERROR(_forward_strs(__VA_ARGS__))
#define ERROR_LOG_F(...) SPDLOG_ERROR(__VA_ARGS__)
1 change: 1 addition & 0 deletions src/input_ncm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ void input_ncm::get_info(file_info &p_info, abort_callback &p_abort) {
reader->get_info(/*sub song*/ 0, p_info, p_abort);

auto mp = meta_processor(p_info);
p_info.meta_remove_all();
mp.update(ncm_file_->meta_info());
mp.apply(p_info);
}
Expand Down
55 changes: 29 additions & 26 deletions src/meta_process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ using json_t = nlohmann::json;

void meta_processor::update(const file_info &info) { // FB2K
using refl_f_t = void(t_size /*enum index*/);
auto reflection = std::unordered_map<std::string_view, std::function<refl_f_t>>{}; // UPPERCASE keys
auto reflection = std::unordered_map<std::string, std::function<refl_f_t>>{}; // UPPERCASE keys
reflection["artist"_upper] = [&](t_size meta_entry) {
auto vc = info.meta_enum_value_count(meta_entry);
if (!vc) {
Expand Down Expand Up @@ -58,9 +58,9 @@ void meta_processor::update(const file_info &info) { // FB2K
reflection["transNames"_upper] = reflect_multi(transNames);

// ignore essential special keys
reflection[foo_input_ncm_comment_key] = [](auto...) {};
reflection[foo_input_ncm_comment_key.data()] = [](auto...) {};
reflection[upper(foo_input_ncm_comment_key)] = [](auto...) {};
reflection[overwrite_key] = [](auto...) {};
reflection[overwrite_key.data()] = [](auto...) {};
reflection[upper(overwrite_key)] = [](auto...) {};

auto meta_count = info.meta_get_count();
Expand All @@ -84,9 +84,13 @@ void meta_processor::update(const file_info &info) { // FB2K
}

void meta_processor::update(const nlohmann::json &json) { // NCM, public
update_by_json(json);
if (json.contains("overwrite")) {
update_by_json(json["overwrite"], true);
try {
update_by_json(json);
if (json.contains("overwrite")) {
update_by_json(json["overwrite"], true);
}
} catch (const std::exception &e) {
ERROR_LOG_F("Error processing meta({}): {}", e.what(), json.dump());
}
}

Expand All @@ -97,7 +101,7 @@ void meta_processor::update_by_json(const nlohmann::json &json, bool overwriting
}

using refl_f_t = void(const nlohmann::json &);
auto reflection = std::unordered_map<std::string_view, std::function<refl_f_t>>{}; // UPPERCASE keys
auto reflection = std::unordered_map<std::string, std::function<refl_f_t>>{}; // UPPERCASE keys
reflection["artist"] = [&](const json_t &j) {
if (j.is_null()) {
artist.reset();
Expand All @@ -113,31 +117,30 @@ void meta_processor::update_by_json(const nlohmann::json &json, bool overwriting
if (val.size() != 2) {
continue;
}
if (!val[0].is_string() || !val[1].is_number_integer()) {
if (!val[0].is_string() /*|| !val[1].is_number_integer()*/) { // ARTIST ID can be str or num
continue;
}
artist->emplace(val[0].get<std::string>(), val[1].get<uint64_t>());
artist->emplace(val[0].get<std::string>(), weak_typed_id(val[1]));
}
};

// NOTE: I found an abnormal case that albumPicId is a number instead of string.
// So I deside to test every possible numeric type and try to convert them.

#define reflect_single(field, TYPE) \
[&](const json_t &j) { \
if (j.is_null()) { \
field.reset(); \
return; \
} \
try { \
update_v(field, j.get<TYPE>()); \
} catch (const json_t::type_error &) { \
if constexpr (std::is_same_v<TYPE, std::string>) { \
update_v(field, std::to_string(j.get<uint64_t>())); \
} else if constexpr (std::is_same_v<TYPE, uint64_t>) { \
update_v(field, std::stoull(j.get<std::string>())); \
} \
} \
#define reflect_single(field, TYPE) \
[&](const json_t &j) { \
if (j.is_null()) { \
field.reset(); \
return; \
} \
try { \
update_v(field, j.get<TYPE>()); \
} catch (const json_t::type_error &) { \
try { \
update_v(field, weak_typed_id(j)); \
} catch (const json_t::type_error &) { \
} \
} \
}
#define reflect_multi_string(field) \
[&](const json_t &j) { \
Expand Down Expand Up @@ -192,9 +195,9 @@ void meta_processor::update_by_json(const nlohmann::json &json, bool overwriting
reflection["Lyrics"_upper] = reflect_single(lyrics, std::string);

// ignore comment key
reflection[foo_input_ncm_comment_key] = [](auto...) { /* DO NOTHING*/ };
reflection[foo_input_ncm_comment_key.data()] = [](auto...) { /* DO NOTHING*/ };
// ignore overwrite currently
reflection[overwrite_key] = [](auto...) {};
reflection[overwrite_key.data()] = [](auto...) {};

for (const auto &[key, val] : json.items()) {
if (reflection.contains(key)) {
Expand Down
25 changes: 25 additions & 0 deletions src/meta_process.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,31 @@ namespace fb2k_ncm
}
} // namespace

namespace
{
class weak_typed_id {
uint64_t n_ = 0;

public:
explicit weak_typed_id(const nlohmann::json &json) {
if (json.is_number_integer()) {
n_ = json.get<uint64_t>();
} else if (json.is_string()) {
n_ = std::stoull(json.get<std::string>());
}
}
explicit weak_typed_id(const std::string &s) : n_(0) {
try {
n_ = std::stoull(s);
} catch (std::invalid_argument &e) {
}
}
explicit weak_typed_id(std::integral auto n) : n_(n) {}
operator uint64_t() const noexcept { return n_; }
operator std::string() const { return std::to_string(n_); }
};
} // namespace

class meta_processor : public uniform_meta_st {
public:
void update(const file_info &info); // FB2K
Expand Down
3 changes: 3 additions & 0 deletions test/sample/dup_extra_meta_mp3_win_ncm3.0.0beta-159431.ncm
Git LFS file not shown

0 comments on commit 6225b53

Please sign in to comment.