Mercurial > foo_out_sdl
comparison foosdk/sdk/foobar2000/SDK/config_object.cpp @ 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 #include "foobar2000-sdk-pch.h" | |
| 2 #include "config_object_impl.h" | |
| 3 #include "configStore.h" | |
| 4 | |
| 5 void config_object_notify_manager::g_on_changed(const service_ptr_t<config_object> & p_object) | |
| 6 { | |
| 7 if (core_api::assert_main_thread()) | |
| 8 { | |
| 9 for (auto ptr : enumerate()) { | |
| 10 ptr->on_changed(p_object); | |
| 11 } | |
| 12 } | |
| 13 } | |
| 14 | |
| 15 bool config_object::g_find(service_ptr_t<config_object> & p_out,const GUID & p_guid) | |
| 16 { | |
| 17 for (auto ptr : enumerate()) { | |
| 18 if (ptr->get_guid() == p_guid) { | |
| 19 p_out = ptr; | |
| 20 return true; | |
| 21 } | |
| 22 } | |
| 23 return false; | |
| 24 } | |
| 25 | |
| 26 void config_object::g_get_data_string(const GUID & p_guid,pfc::string_base & p_out) | |
| 27 { | |
| 28 service_ptr_t<config_object> ptr; | |
| 29 if (!g_find(ptr,p_guid)) throw exception_service_not_found(); | |
| 30 ptr->get_data_string(p_out); | |
| 31 } | |
| 32 | |
| 33 void config_object::g_set_data_string(const GUID & p_guid,const char * p_data,t_size p_length) | |
| 34 { | |
| 35 service_ptr_t<config_object> ptr; | |
| 36 if (!g_find(ptr,p_guid)) throw exception_service_not_found(); | |
| 37 ptr->set_data_string(p_data,p_length); | |
| 38 } | |
| 39 | |
| 40 void config_object::get_data_int32(t_int32 & p_out) | |
| 41 { | |
| 42 t_int32 temp; | |
| 43 get_data_struct_t<t_int32>(temp); | |
| 44 byte_order::order_le_to_native_t(temp); | |
| 45 p_out = temp; | |
| 46 } | |
| 47 | |
| 48 void config_object::set_data_int32(t_int32 p_val) | |
| 49 { | |
| 50 t_int32 temp = p_val; | |
| 51 byte_order::order_native_to_le_t(temp); | |
| 52 set_data_struct_t<t_int32>(temp); | |
| 53 } | |
| 54 | |
| 55 bool config_object::get_data_bool_simple(bool p_default) { | |
| 56 try { | |
| 57 bool ret = p_default; | |
| 58 get_data_bool(ret); | |
| 59 return ret; | |
| 60 } catch(...) {return p_default;} | |
| 61 } | |
| 62 | |
| 63 t_int32 config_object::get_data_int32_simple(t_int32 p_default) { | |
| 64 try { | |
| 65 t_int32 ret = p_default; | |
| 66 get_data_int32(ret); | |
| 67 return ret; | |
| 68 } catch(...) {return p_default;} | |
| 69 } | |
| 70 | |
| 71 void config_object::g_get_data_int32(const GUID & p_guid,t_int32 & p_out) { | |
| 72 service_ptr_t<config_object> ptr; | |
| 73 if (!g_find(ptr,p_guid)) throw exception_service_not_found(); | |
| 74 ptr->get_data_int32(p_out); | |
| 75 } | |
| 76 | |
| 77 void config_object::g_set_data_int32(const GUID & p_guid,t_int32 p_val) { | |
| 78 service_ptr_t<config_object> ptr; | |
| 79 if (!g_find(ptr,p_guid)) throw exception_service_not_found(); | |
| 80 ptr->set_data_int32(p_val); | |
| 81 } | |
| 82 | |
| 83 bool config_object::g_get_data_bool_simple(const GUID & p_guid,bool p_default) | |
| 84 { | |
| 85 service_ptr_t<config_object> ptr; | |
| 86 if (!g_find(ptr,p_guid)) throw exception_service_not_found(); | |
| 87 return ptr->get_data_bool_simple(p_default); | |
| 88 } | |
| 89 | |
| 90 t_int32 config_object::g_get_data_int32_simple(const GUID & p_guid,t_int32 p_default) | |
| 91 { | |
| 92 service_ptr_t<config_object> ptr; | |
| 93 if (!g_find(ptr,p_guid)) throw exception_service_not_found(); | |
| 94 return ptr->get_data_int32_simple(p_default); | |
| 95 } | |
| 96 | |
| 97 void config_object::get_data_bool(bool & p_out) {get_data_struct_t<bool>(p_out);} | |
| 98 void config_object::set_data_bool(bool p_val) {set_data_struct_t<bool>(p_val);} | |
| 99 | |
| 100 void config_object::g_get_data_bool(const GUID & p_guid,bool & p_out) {g_get_data_struct_t<bool>(p_guid,p_out);} | |
| 101 void config_object::g_set_data_bool(const GUID & p_guid,bool p_val) {g_set_data_struct_t<bool>(p_guid,p_val);} | |
| 102 | |
| 103 namespace { | |
| 104 class stream_writer_string : public stream_writer { | |
| 105 public: | |
| 106 void write(const void * p_buffer,t_size p_bytes,abort_callback & p_abort) { | |
| 107 p_abort.check(); | |
| 108 m_out.add_string((const char*)p_buffer,p_bytes); | |
| 109 } | |
| 110 stream_writer_string(pfc::string_base & p_out) : m_out(p_out) {m_out.reset();} | |
| 111 private: | |
| 112 pfc::string_base & m_out; | |
| 113 }; | |
| 114 | |
| 115 class stream_writer_fixedbuffer : public stream_writer { | |
| 116 public: | |
| 117 void write(const void * p_buffer,t_size p_bytes,abort_callback & p_abort) { | |
| 118 p_abort.check(); | |
| 119 if (p_bytes > 0) { | |
| 120 if (p_bytes > m_bytes - m_bytes_read) throw pfc::exception_overflow(); | |
| 121 memcpy((t_uint8*)m_out,p_buffer,p_bytes); | |
| 122 m_bytes_read += p_bytes; | |
| 123 } | |
| 124 } | |
| 125 stream_writer_fixedbuffer(void * p_out,t_size p_bytes,t_size & p_bytes_read) : m_out(p_out), m_bytes(p_bytes), m_bytes_read(p_bytes_read) {m_bytes_read = 0;} | |
| 126 private: | |
| 127 void * m_out; | |
| 128 t_size m_bytes; | |
| 129 t_size & m_bytes_read; | |
| 130 }; | |
| 131 | |
| 132 | |
| 133 | |
| 134 class stream_writer_get_length : public stream_writer { | |
| 135 public: | |
| 136 void write(const void * ,t_size p_bytes,abort_callback & p_abort) override { | |
| 137 p_abort.check(); | |
| 138 m_length += p_bytes; | |
| 139 } | |
| 140 stream_writer_get_length(t_size & p_length) : m_length(p_length) {m_length = 0;} | |
| 141 private: | |
| 142 t_size & m_length; | |
| 143 }; | |
| 144 }; | |
| 145 | |
| 146 t_size config_object::get_data_raw(void * p_out,t_size p_bytes) { | |
| 147 t_size ret = 0; | |
| 148 stream_writer_fixedbuffer stream(p_out,p_bytes,ret); | |
| 149 get_data(&stream,fb2k::noAbort); | |
| 150 return ret; | |
| 151 } | |
| 152 | |
| 153 t_size config_object::get_data_raw_length() { | |
| 154 t_size ret = 0; | |
| 155 stream_writer_get_length stream(ret); | |
| 156 get_data(&stream,fb2k::noAbort); | |
| 157 return ret; | |
| 158 } | |
| 159 | |
| 160 void config_object::set_data_raw(const void * p_data,t_size p_bytes, bool p_notify) { | |
| 161 stream_reader_memblock_ref stream(p_data,p_bytes); | |
| 162 set_data(&stream,fb2k::noAbort,p_notify); | |
| 163 } | |
| 164 | |
| 165 void config_object::set_data_string(const char * p_data,t_size p_length) { | |
| 166 set_data_raw(p_data,pfc::strlen_max(p_data,p_length)); | |
| 167 } | |
| 168 | |
| 169 void config_object::get_data_string(pfc::string_base & p_out) { | |
| 170 stream_writer_string stream(p_out); | |
| 171 get_data(&stream,fb2k::noAbort); | |
| 172 } | |
| 173 | |
| 174 | |
| 175 //config_object_impl stuff | |
| 176 | |
| 177 #if FOOBAR2020 | |
| 178 pfc::string8 config_object_impl::formatName() const { | |
| 179 return pfc::format("config_object.", pfc::print_guid(get_guid())); | |
| 180 } | |
| 181 | |
| 182 void config_object_impl::get_data(stream_writer * p_stream,abort_callback & p_abort) const { | |
| 183 auto blob = fb2k::configStore::get()->getConfigBlob(formatName(), m_initial); | |
| 184 if (blob.is_valid()) p_stream->write(blob->data(), blob->size(), p_abort); | |
| 185 } | |
| 186 | |
| 187 void config_object_impl::set_data(stream_reader * p_stream,abort_callback & p_abort,bool p_notify) { | |
| 188 core_api::ensure_main_thread(); | |
| 189 | |
| 190 { | |
| 191 pfc::mem_block data; | |
| 192 enum {delta = 1024}; | |
| 193 t_uint8 buffer[delta]; | |
| 194 for(;;) | |
| 195 { | |
| 196 t_size delta_done = p_stream->read(buffer,delta,p_abort); | |
| 197 | |
| 198 if (delta_done > 0) | |
| 199 { | |
| 200 data.append_fromptr(buffer,delta_done); | |
| 201 } | |
| 202 | |
| 203 if (delta_done != delta) break; | |
| 204 } | |
| 205 | |
| 206 auto blob = fb2k::memBlock::blockWithData(std::move(data)); | |
| 207 fb2k::configStore::get()->setConfigBlob(formatName(), blob); | |
| 208 } | |
| 209 | |
| 210 if (p_notify) config_object_notify_manager::g_on_changed(this); | |
| 211 } | |
| 212 | |
| 213 config_object_impl::config_object_impl(const GUID & p_guid,const void * p_data,t_size p_bytes) : cfg_var_reader(p_guid) | |
| 214 { | |
| 215 if (p_bytes > 0) m_initial = fb2k::makeMemBlock(p_data, p_bytes); | |
| 216 } | |
| 217 #else // FOOBAR2020 | |
| 218 void config_object_impl::get_data(stream_writer* p_stream, abort_callback& p_abort) const { | |
| 219 inReadSync(m_sync); | |
| 220 p_stream->write_object(m_data.get_ptr(), m_data.get_size(), p_abort); | |
| 221 } | |
| 222 | |
| 223 void config_object_impl::set_data(stream_reader* p_stream, abort_callback& p_abort, bool p_notify) { | |
| 224 core_api::ensure_main_thread(); | |
| 225 | |
| 226 { | |
| 227 inWriteSync(m_sync); | |
| 228 m_data.set_size(0); | |
| 229 enum { delta = 1024 }; | |
| 230 t_uint8 buffer[delta]; | |
| 231 for (;;) | |
| 232 { | |
| 233 t_size delta_done = p_stream->read(buffer, delta, p_abort); | |
| 234 | |
| 235 if (delta_done > 0) | |
| 236 { | |
| 237 m_data.append_fromptr(buffer, delta_done); | |
| 238 } | |
| 239 | |
| 240 if (delta_done != delta) break; | |
| 241 } | |
| 242 } | |
| 243 | |
| 244 if (p_notify) config_object_notify_manager::g_on_changed(this); | |
| 245 } | |
| 246 | |
| 247 config_object_impl::config_object_impl(const GUID& p_guid, const void* p_data, t_size p_bytes) : cfg_var(p_guid) | |
| 248 { | |
| 249 m_data.set_data_fromptr((const t_uint8*)p_data, p_bytes); | |
| 250 } | |
| 251 #endif |
