Mercurial > foo_out_sdl
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 0:e9bb126753e7 | 1:20d02a178406 |
|---|---|
| 1 #pragma once | |
| 2 | |
| 3 class _meta_table_enum_wrapper { | |
| 4 public: | |
| 5 _meta_table_enum_wrapper(file_info & p_info) : m_info(p_info) {} | |
| 6 template<typename t_values> | |
| 7 void operator() (const char * p_name,const t_values & p_values) { | |
| 8 t_size index = ~0; | |
| 9 for(typename t_values::const_iterator iter = p_values.first(); iter.is_valid(); ++iter) { | |
| 10 if (index == ~0) index = m_info.__meta_add_unsafe(p_name,*iter); | |
| 11 else m_info.meta_add_value(index,*iter); | |
| 12 } | |
| 13 } | |
| 14 private: | |
| 15 file_info & m_info; | |
| 16 }; | |
| 17 | |
| 18 class _meta_table_enum_wrapper_RG { | |
| 19 public: | |
| 20 _meta_table_enum_wrapper_RG(file_info & p_info) : m_info(p_info) {} | |
| 21 template<typename t_values> | |
| 22 void operator() (const char * p_name,const t_values & p_values) { | |
| 23 if (p_values.get_count() > 0) { | |
| 24 if (!m_info.info_set_replaygain(p_name, *p_values.first())) { | |
| 25 t_size index = ~0; | |
| 26 for(typename t_values::const_iterator iter = p_values.first(); iter.is_valid(); ++iter) { | |
| 27 if (index == ~0) index = m_info.__meta_add_unsafe(p_name,*iter); | |
| 28 else m_info.meta_add_value(index,*iter); | |
| 29 } | |
| 30 } | |
| 31 } | |
| 32 } | |
| 33 private: | |
| 34 file_info & m_info; | |
| 35 }; | |
| 36 | |
| 37 //! Purpose: building a file_info metadata table from loose input without search-for-existing-entry bottleneck | |
| 38 class meta_table_builder { | |
| 39 public: | |
| 40 typedef pfc::chain_list_v2_t<pfc::string8> t_entry; | |
| 41 typedef pfc::map_t<pfc::string8,t_entry,file_info::field_name_comparator> t_content; | |
| 42 | |
| 43 t_content & content() {return m_data;} | |
| 44 t_content const & content() const {return m_data;} | |
| 45 | |
| 46 void add(const char * p_name,const char * p_value,t_size p_value_len = ~0) { | |
| 47 if (file_info::g_is_valid_field_name(p_name)) { | |
| 48 _add(p_name).insert_last()->set_string(p_value,p_value_len); | |
| 49 } | |
| 50 } | |
| 51 | |
| 52 void remove(const char * p_name) { | |
| 53 m_data.remove(p_name); | |
| 54 } | |
| 55 void set(const char * p_name,const char * p_value,t_size p_value_len = ~0) { | |
| 56 if (file_info::g_is_valid_field_name(p_name)) { | |
| 57 t_entry & entry = _add(p_name); | |
| 58 entry.remove_all(); | |
| 59 entry.insert_last()->set_string(p_value,p_value_len); | |
| 60 } | |
| 61 } | |
| 62 t_entry & add(const char * p_name) { | |
| 63 if (!file_info::g_is_valid_field_name(p_name)) uBugCheck();//we return a reference, nothing smarter to do | |
| 64 return _add(p_name); | |
| 65 } | |
| 66 void deduplicate(const char * name) { | |
| 67 t_entry * e; | |
| 68 if (!m_data.query_ptr(name, e)) return; | |
| 69 pfc::avltree_t<const char*, pfc::comparator_strcmp> found; | |
| 70 for(t_entry::iterator iter = e->first(); iter.is_valid(); ) { | |
| 71 t_entry::iterator next = iter; ++next; | |
| 72 const char * v = *iter; | |
| 73 if (!found.add_item_check(v)) e->remove(iter); | |
| 74 iter = next; | |
| 75 } | |
| 76 } | |
| 77 void keep_one(const char * name) { | |
| 78 t_entry * e; | |
| 79 if (!m_data.query_ptr(name, e)) return; | |
| 80 while(e->get_count() > 1) e->remove(e->last()); | |
| 81 } | |
| 82 void tidy_VorbisComment() { | |
| 83 deduplicate("album artist"); | |
| 84 deduplicate("publisher"); | |
| 85 keep_one("totaltracks"); | |
| 86 keep_one("totaldiscs"); | |
| 87 } | |
| 88 void finalize(file_info & p_info) const { | |
| 89 p_info.meta_remove_all(); | |
| 90 _meta_table_enum_wrapper e(p_info); | |
| 91 m_data.enumerate(e); | |
| 92 } | |
| 93 void finalize_withRG(file_info & p_info) const { | |
| 94 p_info.meta_remove_all(); p_info.set_replaygain(replaygain_info_invalid); | |
| 95 _meta_table_enum_wrapper_RG e(p_info); | |
| 96 m_data.enumerate(e); | |
| 97 } | |
| 98 | |
| 99 void from_info(const file_info & p_info) { | |
| 100 m_data.remove_all(); | |
| 101 from_info_overwrite(p_info); | |
| 102 } | |
| 103 void from_info_withRG(const file_info & p_info) { | |
| 104 m_data.remove_all(); | |
| 105 from_info_overwrite(p_info); | |
| 106 from_RG_overwrite(p_info.get_replaygain()); | |
| 107 } | |
| 108 void from_RG_overwrite(replaygain_info const & info) { | |
| 109 info.for_each([&](const char* key, const char* value) { | |
| 110 set(key, value); | |
| 111 }); | |
| 112 } | |
| 113 void from_info_overwrite(const file_info & p_info) { | |
| 114 for(t_size metawalk = 0, metacount = p_info.meta_get_count(); metawalk < metacount; ++metawalk ) { | |
| 115 const t_size valuecount = p_info.meta_enum_value_count(metawalk); | |
| 116 if (valuecount > 0) { | |
| 117 t_entry & entry = add(p_info.meta_enum_name(metawalk)); | |
| 118 entry.remove_all(); | |
| 119 for(t_size valuewalk = 0; valuewalk < valuecount; ++valuewalk) { | |
| 120 entry.insert_last(p_info.meta_enum_value(metawalk,valuewalk)); | |
| 121 } | |
| 122 } | |
| 123 } | |
| 124 } | |
| 125 void reset() {m_data.remove_all();} | |
| 126 | |
| 127 void fix_itunes_compilation() { | |
| 128 auto entry = m_data.find("itunescompilation"); | |
| 129 if (entry.is_valid()) { | |
| 130 auto val = entry->m_value.first(); | |
| 131 if (val.is_valid()) { | |
| 132 if (atoi(val->c_str()) != 0) { | |
| 133 // m_data.remove(cmp); | |
| 134 if (!m_data.have_item("album artist")) add("album artist", "Various Artists"); | |
| 135 } | |
| 136 } | |
| 137 } | |
| 138 } | |
| 139 private: | |
| 140 | |
| 141 t_entry & _add(const char * p_name) { | |
| 142 return m_data.find_or_add(p_name); | |
| 143 } | |
| 144 | |
| 145 t_content m_data; | |
| 146 }; |
