commit d7bae530977046a658238dd74c694022c76231a2
parent cad1d21630d87502da4b91495978a193f3e5fff3
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date: Sat, 27 Apr 2024 15:17:55 +0200
fix unhandled exception while reading patch manager cache
Diffstat:
1 file changed, 147 insertions(+), 139 deletions(-)
diff --git a/source/jucePluginLib/patchdb/db.cpp b/source/jucePluginLib/patchdb/db.cpp
@@ -1690,194 +1690,202 @@ namespace pluginLib::patchDB
if(!synthLib::readFile(data, m_cacheFileName.getFullPathName().toStdString()))
return false;
- synthLib::BinaryStream inStream(data);
-
- auto stream = inStream.tryReadChunk(chunks::g_patchManager);
-
- if(!stream)
- return false;
+ try
+ {
+ synthLib::BinaryStream inStream(data);
- std::unique_lock lockDS(m_dataSourcesMutex);
- std::unique_lock lockP(m_patchesMutex);
+ auto stream = inStream.tryReadChunk(chunks::g_patchManager);
- std::map<DataSource, DataSourceNodePtr> resultDataSources;
- std::unordered_map<TagType, std::set<Tag>> resultTags;
- std::unordered_map<TagType, std::unordered_map<Tag, uint32_t>> resultTagColors;
- std::map<PatchKey, PatchModificationsPtr> resultPatchModifications;
+ if(!stream)
+ return false;
- if(auto s = stream.tryReadChunk(chunks::g_patchManagerDataSources, 1))
- {
- const auto numDatasources = s.read<uint32_t>();
+ std::unique_lock lockDS(m_dataSourcesMutex);
+ std::unique_lock lockP(m_patchesMutex);
- std::vector<DataSource> dataSources;
- dataSources.reserve(numDatasources);
+ std::map<DataSource, DataSourceNodePtr> resultDataSources;
+ std::unordered_map<TagType, std::set<Tag>> resultTags;
+ std::unordered_map<TagType, std::unordered_map<Tag, uint32_t>> resultTagColors;
+ std::map<PatchKey, PatchModificationsPtr> resultPatchModifications;
- for(uint32_t i=0; i<numDatasources; ++i)
+ if(auto s = stream.tryReadChunk(chunks::g_patchManagerDataSources, 1))
{
- DataSource& ds = dataSources.emplace_back();
- if(!ds.read(s))
- return false;
- }
+ const auto numDatasources = s.read<uint32_t>();
- // read tree information
- std::map<uint32_t, uint32_t> childToParentMap;
- const auto childToParentCount = s.read<uint32_t>();
- for(uint32_t i=0; i<childToParentCount; ++i)
- {
- const auto child = s.read<uint32_t>();
- const auto parent = s.read<uint32_t>();
- childToParentMap.insert({child, parent});
- }
+ std::vector<DataSource> dataSources;
+ dataSources.reserve(numDatasources);
- std::vector<DataSourceNodePtr> nodes;
- nodes.resize(dataSources.size());
+ for(uint32_t i=0; i<numDatasources; ++i)
+ {
+ DataSource& ds = dataSources.emplace_back();
+ if(!ds.read(s))
+ return false;
+ }
- // create root nodes first
- for(uint32_t i=0; i<dataSources.size(); ++i)
- {
- if(childToParentMap.find(i) != childToParentMap.end())
- continue;
+ // read tree information
+ std::map<uint32_t, uint32_t> childToParentMap;
+ const auto childToParentCount = s.read<uint32_t>();
+ for(uint32_t i=0; i<childToParentCount; ++i)
+ {
+ const auto child = s.read<uint32_t>();
+ const auto parent = s.read<uint32_t>();
+ childToParentMap.insert({child, parent});
+ }
- const auto& ds = dataSources[i];
- const auto node = std::make_shared<DataSourceNode>(ds);
- nodes[i] = node;
- resultDataSources.insert({ds, node});
- }
+ std::vector<DataSourceNodePtr> nodes;
+ nodes.resize(dataSources.size());
- // now iteratively create children until there are none left
- while(!childToParentMap.empty())
- {
- for(auto it = childToParentMap.begin(); it != childToParentMap.end();)
+ // create root nodes first
+ for(uint32_t i=0; i<dataSources.size(); ++i)
{
- const auto childId = it->first;
- const auto parentId = it->second;
-
- const auto& parent = nodes[parentId];
- if(!parent)
- {
- ++it;
+ if(childToParentMap.find(i) != childToParentMap.end())
continue;
- }
- const auto& ds = dataSources[childId];
+ const auto& ds = dataSources[i];
const auto node = std::make_shared<DataSourceNode>(ds);
- node->setParent(parent);
- nodes[childId] = node;
+ nodes[i] = node;
resultDataSources.insert({ds, node});
+ }
+
+ // now iteratively create children until there are none left
+ while(!childToParentMap.empty())
+ {
+ for(auto it = childToParentMap.begin(); it != childToParentMap.end();)
+ {
+ const auto childId = it->first;
+ const auto parentId = it->second;
- it = childToParentMap.erase(it);
+ const auto& parent = nodes[parentId];
+ if(!parent)
+ {
+ ++it;
+ continue;
+ }
+
+ const auto& ds = dataSources[childId];
+ const auto node = std::make_shared<DataSourceNode>(ds);
+ node->setParent(parent);
+ nodes[childId] = node;
+ resultDataSources.insert({ds, node});
+
+ it = childToParentMap.erase(it);
+ }
}
- }
- // now as we have the datasources created as nodes, patches need to know the datasource nodes they are part of
- for (const auto& it : resultDataSources)
- {
- for(auto& patch : it.second->patches)
- patch->source = it.second->weak_from_this();
+ // now as we have the datasources created as nodes, patches need to know the datasource nodes they are part of
+ for (const auto& it : resultDataSources)
+ {
+ for(auto& patch : it.second->patches)
+ patch->source = it.second->weak_from_this();
+ }
}
- }
- else
- return false;
-
- if(auto s = stream.tryReadChunk(chunks::g_patchManagerTags, 1))
- {
- const auto tagTypeCount = s.read<uint32_t>();
+ else
+ return false;
- for(uint32_t i=0; i<tagTypeCount; ++i)
+ if(auto s = stream.tryReadChunk(chunks::g_patchManagerTags, 1))
{
- const auto tagType = static_cast<TagType>(s.read<uint8_t>());
- const auto tagCount = s.read<uint32_t>();
+ const auto tagTypeCount = s.read<uint32_t>();
- std::set<Tag> tags;
- for(uint32_t t=0; t<tagCount; ++t)
- tags.insert(s.readString());
+ for(uint32_t i=0; i<tagTypeCount; ++i)
+ {
+ const auto tagType = static_cast<TagType>(s.read<uint8_t>());
+ const auto tagCount = s.read<uint32_t>();
- resultTags.insert({tagType, tags});
- }
- }
- else
- return false;
+ std::set<Tag> tags;
+ for(uint32_t t=0; t<tagCount; ++t)
+ tags.insert(s.readString());
- if(auto s = stream.tryReadChunk(chunks::g_patchManagerTagColors, 1))
- {
- const auto tagTypeCount = s.read<uint32_t>();
+ resultTags.insert({tagType, tags});
+ }
+ }
+ else
+ return false;
- for(uint32_t i=0; i<tagTypeCount; ++i)
+ if(auto s = stream.tryReadChunk(chunks::g_patchManagerTagColors, 1))
{
- const auto tagType = static_cast<TagType>(s.read<uint8_t>());
- std::unordered_map<Tag, Color> tagToColor;
+ const auto tagTypeCount = s.read<uint32_t>();
- const auto count = s.read<uint32_t>();
- for(uint32_t c=0; c<count; ++c)
+ for(uint32_t i=0; i<tagTypeCount; ++i)
{
- const auto tag = s.readString();
- const auto color = s.read<Color>();
- tagToColor.insert({tag, color});
+ const auto tagType = static_cast<TagType>(s.read<uint8_t>());
+ std::unordered_map<Tag, Color> tagToColor;
+
+ const auto count = s.read<uint32_t>();
+ for(uint32_t c=0; c<count; ++c)
+ {
+ const auto tag = s.readString();
+ const auto color = s.read<Color>();
+ tagToColor.insert({tag, color});
+ }
+ resultTagColors.insert({tagType, tagToColor});
}
- resultTagColors.insert({tagType, tagToColor});
}
- }
- else
- return false;
-
- if(auto s = stream.tryReadChunk(chunks::g_patchManagerPatchModifications, 1))
- {
- const auto count = s.read<uint32_t>();
+ else
+ return false;
- for(uint32_t i=0; i<count; ++i)
+ if(auto s = stream.tryReadChunk(chunks::g_patchManagerPatchModifications, 1))
{
- auto key = PatchKey::fromString(s.readString());
+ const auto count = s.read<uint32_t>();
- const auto itDS = resultDataSources.find(*key.source);
- if(itDS != resultDataSources.end())
- key.source = itDS->second;
+ for(uint32_t i=0; i<count; ++i)
+ {
+ auto key = PatchKey::fromString(s.readString());
- auto mods = std::make_shared<PatchModifications>();
- if(!mods->read(s))
- return false;
+ const auto itDS = resultDataSources.find(*key.source);
+ if(itDS != resultDataSources.end())
+ key.source = itDS->second;
- resultPatchModifications.insert({key, mods});
+ auto mods = std::make_shared<PatchModifications>();
+ if(!mods->read(s))
+ return false;
- for (const auto& it : resultDataSources)
- {
- for (const auto& patch : it.second->patches)
+ resultPatchModifications.insert({key, mods});
+
+ for (const auto& it : resultDataSources)
{
- if(*patch != key)
- continue;
+ for (const auto& patch : it.second->patches)
+ {
+ if(*patch != key)
+ continue;
- patch->modifications = mods;
- mods->patch = patch;
+ patch->modifications = mods;
+ mods->patch = patch;
+ }
}
}
}
- }
- else
- return false;
+ else
+ return false;
- m_dataSources = resultDataSources;
- m_tags = resultTags;
- m_tagColors = resultTagColors;
- m_patchModifications = resultPatchModifications;
+ m_dataSources = resultDataSources;
+ m_tags = resultTags;
+ m_tagColors = resultTagColors;
+ m_patchModifications = resultPatchModifications;
- for (const auto& it: resultDataSources)
- {
- const auto& patches = it.second->patches;
- updateSearches({patches.begin(), patches.end()});
- }
+ for (const auto& it: resultDataSources)
+ {
+ const auto& patches = it.second->patches;
+ updateSearches({patches.begin(), patches.end()});
+ }
- {
- std::unique_lock lockUi(m_uiMutex);
+ {
+ std::unique_lock lockUi(m_uiMutex);
- m_dirty.dataSources = true;
- m_dirty.patches = true;
+ m_dirty.dataSources = true;
+ m_dirty.patches = true;
- for (const auto& it : m_tags)
- m_dirty.tags.insert(it.first);
- }
+ for (const auto& it : m_tags)
+ m_dirty.tags.insert(it.first);
+ }
- m_cacheDirty = false;
+ m_cacheDirty = false;
- return true;
+ return true;
+ }
+ catch(const std::range_error& e)
+ {
+ LOG("Failed to read patch manager cache, " << e.what());
+ return false;
+ }
}
void DB::saveCache()