Mercurial > foo_out_sdl
diff foosdk/sdk/foobar2000/helpers/meta_table_builder.h @ 1:20d02a178406 default tip
*: check in everything else
yay
| author | Paper <paper@tflc.us> |
|---|---|
| date | Mon, 05 Jan 2026 02:15:46 -0500 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/foosdk/sdk/foobar2000/helpers/meta_table_builder.h Mon Jan 05 02:15:46 2026 -0500 @@ -0,0 +1,146 @@ +#pragma once + +class _meta_table_enum_wrapper { +public: + _meta_table_enum_wrapper(file_info & p_info) : m_info(p_info) {} + template<typename t_values> + void operator() (const char * p_name,const t_values & p_values) { + t_size index = ~0; + for(typename t_values::const_iterator iter = p_values.first(); iter.is_valid(); ++iter) { + if (index == ~0) index = m_info.__meta_add_unsafe(p_name,*iter); + else m_info.meta_add_value(index,*iter); + } + } +private: + file_info & m_info; +}; + +class _meta_table_enum_wrapper_RG { +public: + _meta_table_enum_wrapper_RG(file_info & p_info) : m_info(p_info) {} + template<typename t_values> + void operator() (const char * p_name,const t_values & p_values) { + if (p_values.get_count() > 0) { + if (!m_info.info_set_replaygain(p_name, *p_values.first())) { + t_size index = ~0; + for(typename t_values::const_iterator iter = p_values.first(); iter.is_valid(); ++iter) { + if (index == ~0) index = m_info.__meta_add_unsafe(p_name,*iter); + else m_info.meta_add_value(index,*iter); + } + } + } + } +private: + file_info & m_info; +}; + +//! Purpose: building a file_info metadata table from loose input without search-for-existing-entry bottleneck +class meta_table_builder { +public: + typedef pfc::chain_list_v2_t<pfc::string8> t_entry; + typedef pfc::map_t<pfc::string8,t_entry,file_info::field_name_comparator> t_content; + + t_content & content() {return m_data;} + t_content const & content() const {return m_data;} + + void add(const char * p_name,const char * p_value,t_size p_value_len = ~0) { + if (file_info::g_is_valid_field_name(p_name)) { + _add(p_name).insert_last()->set_string(p_value,p_value_len); + } + } + + void remove(const char * p_name) { + m_data.remove(p_name); + } + void set(const char * p_name,const char * p_value,t_size p_value_len = ~0) { + if (file_info::g_is_valid_field_name(p_name)) { + t_entry & entry = _add(p_name); + entry.remove_all(); + entry.insert_last()->set_string(p_value,p_value_len); + } + } + t_entry & add(const char * p_name) { + if (!file_info::g_is_valid_field_name(p_name)) uBugCheck();//we return a reference, nothing smarter to do + return _add(p_name); + } + void deduplicate(const char * name) { + t_entry * e; + if (!m_data.query_ptr(name, e)) return; + pfc::avltree_t<const char*, pfc::comparator_strcmp> found; + for(t_entry::iterator iter = e->first(); iter.is_valid(); ) { + t_entry::iterator next = iter; ++next; + const char * v = *iter; + if (!found.add_item_check(v)) e->remove(iter); + iter = next; + } + } + void keep_one(const char * name) { + t_entry * e; + if (!m_data.query_ptr(name, e)) return; + while(e->get_count() > 1) e->remove(e->last()); + } + void tidy_VorbisComment() { + deduplicate("album artist"); + deduplicate("publisher"); + keep_one("totaltracks"); + keep_one("totaldiscs"); + } + void finalize(file_info & p_info) const { + p_info.meta_remove_all(); + _meta_table_enum_wrapper e(p_info); + m_data.enumerate(e); + } + void finalize_withRG(file_info & p_info) const { + p_info.meta_remove_all(); p_info.set_replaygain(replaygain_info_invalid); + _meta_table_enum_wrapper_RG e(p_info); + m_data.enumerate(e); + } + + void from_info(const file_info & p_info) { + m_data.remove_all(); + from_info_overwrite(p_info); + } + void from_info_withRG(const file_info & p_info) { + m_data.remove_all(); + from_info_overwrite(p_info); + from_RG_overwrite(p_info.get_replaygain()); + } + void from_RG_overwrite(replaygain_info const & info) { + info.for_each([&](const char* key, const char* value) { + set(key, value); + }); + } + void from_info_overwrite(const file_info & p_info) { + for(t_size metawalk = 0, metacount = p_info.meta_get_count(); metawalk < metacount; ++metawalk ) { + const t_size valuecount = p_info.meta_enum_value_count(metawalk); + if (valuecount > 0) { + t_entry & entry = add(p_info.meta_enum_name(metawalk)); + entry.remove_all(); + for(t_size valuewalk = 0; valuewalk < valuecount; ++valuewalk) { + entry.insert_last(p_info.meta_enum_value(metawalk,valuewalk)); + } + } + } + } + void reset() {m_data.remove_all();} + + void fix_itunes_compilation() { + auto entry = m_data.find("itunescompilation"); + if (entry.is_valid()) { + auto val = entry->m_value.first(); + if (val.is_valid()) { + if (atoi(val->c_str()) != 0) { + // m_data.remove(cmp); + if (!m_data.have_item("album artist")) add("album artist", "Various Artists"); + } + } + } + } +private: + + t_entry & _add(const char * p_name) { + return m_data.find_or_add(p_name); + } + + t_content m_data; +};
