Skip to content

Commit

Permalink
fix: edge cases
Browse files Browse the repository at this point in the history
  • Loading branch information
pnck committed May 5, 2024
1 parent 2fdd102 commit 2cf2ae6
Show file tree
Hide file tree
Showing 11 changed files with 60 additions and 30 deletions.
1 change: 1 addition & 0 deletions .github/workflows/build-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ jobs:
run: |
TAG=$(git describe --tags)
VERSION=${TAG:1}
echo "" >> src/stdafx.h
echo "#define CURRENT_VERSION $VERSION" >> src/stdafx.h
echo "----------------------------"
cat src/stdafx.h
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ jobs:
run: |
TAG=$(git describe --long --all)
VERSION=${TAG:6}
echo "" >> src/stdafx.h
echo "#define CURRENT_VERSION $VERSION" >> src/stdafx.h
echo "----------------------------"
cat src/stdafx.h
Expand Down
2 changes: 2 additions & 0 deletions foo_input_ncm.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ copy $(TargetPath) $(ProjectDir)dist\$(Platform)\</Command>
<ClInclude Include="src\common\helpers.hpp" />
<ClInclude Include="src\common\log.hpp" />
<ClInclude Include="src\common\platform.hpp" />
<ClInclude Include="src\meta_process.hpp" />
<ClInclude Include="src\ui\context_menu.hpp" />
<ClInclude Include="src\input_ncm.hpp" />
<ClInclude Include="src\ncm_file.hpp" />
Expand All @@ -209,6 +210,7 @@ copy $(TargetPath) $(ProjectDir)dist\$(Platform)\</Command>
<ClCompile Include="src\cipher\abnormal_RC4.cpp" />
<ClCompile Include="src\cipher\aes_common.cpp" />
<ClCompile Include="src\cipher\aes_win32.cpp" />
<ClCompile Include="src\meta_process.cpp" />
<ClCompile Include="src\ui\context_menu.cpp" />
<ClCompile Include="src\input_ncm.cpp" />
<ClCompile Include="src\main.cpp" />
Expand Down
6 changes: 6 additions & 0 deletions foo_input_ncm.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@
<ClInclude Include="src\common\log.hpp">
<Filter>Header Files\common</Filter>
</ClInclude>
<ClInclude Include="src\meta_process.hpp">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\album_art_extractor.cpp">
Expand Down Expand Up @@ -101,5 +104,8 @@
<ClCompile Include="src\ui\context_menu.cpp">
<Filter>Source Files\ui</Filter>
</ClCompile>
<ClCompile Include="src\meta_process.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>
5 changes: 3 additions & 2 deletions src/cipher/aes_win32.cpp
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ size_t AES_context_win32::do_crypt_universal( // -*-
throw cipher_error("BCryptDecrypt failed", status_);
}
} else if (op == OP::ENC) {
auto padding_mode = (M == aes_chain_mode::ECB ? 0 : BCRYPT_BLOCK_PADDING);
if (auto status_ = BCryptEncrypt( // -*-
h_key,
(PUCHAR)src,
Expand All @@ -118,7 +119,7 @@ size_t AES_context_win32::do_crypt_universal( // -*-
NULL,
0,
&required_size,
BCRYPT_BLOCK_PADDING);
padding_mode);
!SUCCESS(status_)) {
throw cipher_error("Cannot get required size", status_);
}
Expand All @@ -135,7 +136,7 @@ size_t AES_context_win32::do_crypt_universal( // -*-
(PUCHAR)dst,
(ULONG)cb_dst,
&required_size,
BCRYPT_BLOCK_PADDING);
padding_mode);
!SUCCESS(status_)) {
throw cipher_error("BCryptEncrypt failed", status_);
}
Expand Down
2 changes: 1 addition & 1 deletion src/common/helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ namespace
struct decay_string : public std::string {
using base_t = std::string;
constexpr decay_string() : base_t() {}
decay_string(base_t &&str) noexcept : base_t(std::move(str)) {}
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()}; }
};
Expand Down
5 changes: 5 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
Change Log
Version 0.5.0
- Support of ReplayGain and retagging
- Tags in the audio content and the embedded JSON metainfo are left untouched.
Retagging works on top of them by introduce new overwrite fields.
Version 0.4.1
- Concurrency support for batch conversion
- Add progress UI for batch conversion
Expand Down
16 changes: 15 additions & 1 deletion src/meta_process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,21 @@ void meta_processor::update_by_json(const nlohmann::json &json, bool overwriting
}
};

#define reflect_single(field, TYPE) [&](const json_t &j) { update_v(field, j.get<TYPE>()); };
// 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) { \
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_multi_string(field) \
[&](const json_t &j) { \
if (!j.is_array()) { \
Expand Down
9 changes: 5 additions & 4 deletions src/meta_process.hpp
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ namespace fb2k_ncm

template <optionalT T>
consteval static bool opt_is_multi() {
using CT = std::remove_cvref_t<decltype(*std::declval<T>())>;
if constexpr (requires { CT{}.~unordered_set(); }) {
if constexpr (requires(T t) { t->~unordered_set(); }) {
return true;
} else {
return false;
Expand All @@ -47,9 +46,11 @@ namespace fb2k_ncm
concept multiT = opt_is_multi<T>();

consteval void traits_tests() {
static_assert(singleT<decltype(uniform_meta_st{}.album)>, "check your template implementation");
static_assert(multiT<decltype(uniform_meta_st{}.genre)>, "check your template implementation");
using ST = decltype(uniform_meta_st{}.album);
using MT = decltype(uniform_meta_st{}.genre);
using artistT = decltype(uniform_meta_st{}.artist);
static_assert(singleT<ST>, "check your template implementation");
static_assert(multiT<MT>, "check your template implementation");
static_assert(!singleT<artistT> && !multiT<artistT>, "check your template implementation");
}
} // namespace
Expand Down
41 changes: 20 additions & 21 deletions src/ncm_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,21 @@ inline void ncm_file::throw_format_error(const std::string &extra) {
throw_format_error(extra.c_str());
}

auto ncm_file::make_seek_guard(abort_callback &p_abort) {
auto defer =
[this, &p_abort, p = source_->get_position(p_abort), off = parsed_file_.audio_content_offset, &parsed = parsed_file_](...) {
// RAII guard, will seek back when function returns
if (p > off) { // lands in audio
source_->seek(parsed.audio_content_offset + (p - off), p_abort);
} else {
source_->seek(p, p_abort);
}
};
// NOTE: std::unique_ptr doesn't work because of its special treatment of nullptr.
// defer function will not be called if a nullptr is being "deleted"
return std::shared_ptr<void>(nullptr, defer);
}

t_size fb2k_ncm::ncm_file::read(void *p_buffer, t_size p_bytes, abort_callback &p_abort) {
ensure_audio_offset();
ENSURE_DECRYPTOR();
Expand All @@ -64,7 +79,6 @@ t_size fb2k_ncm::ncm_file::read(void *p_buffer, t_size p_bytes, abort_callback &
return total;
}

/// @attention This function is not implemented / not in use
void fb2k_ncm::ncm_file::write(const void *p_buffer, t_size p_bytes, abort_callback &p_abort) {
ensure_audio_offset();
auto source_pos = source_->get_position(p_abort);
Expand Down Expand Up @@ -128,21 +142,6 @@ t_filetimestamp fb2k_ncm::ncm_file::get_timestamp(abort_callback &p_abort) {
return source_->get_timestamp(p_abort);
}

auto ncm_file::make_seek_guard(abort_callback &p_abort) {
auto defer =
[this, &p_abort, p = source_->get_position(p_abort), off = parsed_file_.audio_content_offset, &parsed = parsed_file_](...) {
// RAII guard, will seek back when function returns
if (p > off) { // lands in audio
source_->seek(parsed.audio_content_offset + (p - off), p_abort);
} else {
source_->seek(p, p_abort);
}
};
// NOTE: std::unique_ptr doesn't work because of its special treatment of nullptr.
// defer function will not be called if a nullptr is being "deleted"
return std::shared_ptr<void>(nullptr, defer);
}

void ncm_file::parse(uint16_t to_parse /* = 0xff*/) {

// NOTE:
Expand Down Expand Up @@ -237,7 +236,7 @@ void ncm_file::parse(uint16_t to_parse /* = 0xff*/) {
if (!meta_json_.is_object()) {
WARN_LOG("Failed to parse meta info of ncm file: ", this->path());
} else {
DEBUG_LOG("Parsed NCM Meta: ", meta_json_.dump(2));
// DEBUG_LOG("Parsed NCM Meta: ", meta_json_.dump(2));
// overwrite takes effect when get_info() => meta_processor::update()
}
}
Expand Down Expand Up @@ -287,7 +286,7 @@ bool ncm_file::save_raw_audio(const char *to_dir, abort_callback &p_abort) {
output.add_filename(pfc::string_filename(this->path()));
output += ext();

auto _seek_guard_ = make_seek_guard(p_abort);
auto _seek_guard_ = make_seek_guard(fb2k::noAbort);

// NOTE:
// If g_open_write_new() opens a file that is being played, the playback will be broken, and the file content will be truncated.
Expand All @@ -299,8 +298,8 @@ bool ncm_file::save_raw_audio(const char *to_dir, abort_callback &p_abort) {
try {
file_ptr file_raw;
filesystem::g_open_write_new(file_raw, output, p_abort);

if (auto size = file_v2::g_transfer(this, file_raw.get_ptr(), get_size(p_abort), p_abort); size == get_size(p_abort)) {
this->seek(0, p_abort);
if (auto size = file_v2::g_transfer(this, file_raw.get_ptr(), this->get_size(p_abort), p_abort); size == this->get_size(p_abort)) {
DEBUG_LOG("Extraction done: ", output);
path_raw_saved_to_ = output;
return true;
Expand Down Expand Up @@ -351,7 +350,7 @@ void ncm_file::overwrite_meta(const nlohmann::json &meta, abort_callback &p_abor

size_t meta_aligned_size = cipher::aligned(meta_str_to_write.size());
auto _step1_handle_padding = [&] {
uint8_t padding = meta_aligned_size - meta_str_to_write.size();
uint8_t padding = static_cast<uint8_t>(meta_aligned_size - meta_str_to_write.size());
meta_str_to_write.reserve(meta_aligned_size);
for (auto i = meta_str_to_write.size(); i < meta_aligned_size; ++i) {
meta_str_to_write.push_back(padding);
Expand Down
2 changes: 1 addition & 1 deletion src/stdafx.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@
#include "foobar2000/SDK/foobar2000.h"
#endif

#define PEOJECT_HOST_REPO "https://github.com/pnck/foo_input_ncm"
#define PEOJECT_HOST_REPO "https://github.com/pnck/foo_input_ncm"

0 comments on commit 2cf2ae6

Please sign in to comment.