Minor changes in .aseprite decoder/encoder to avoid depending on exceptions to control flow

This commit is contained in:
David Capello 2023-01-09 12:31:09 -03:00
parent 178702730b
commit bb3ba19fc6
3 changed files with 40 additions and 24 deletions

View File

@ -1526,23 +1526,23 @@ static void ase_file_write_properties_maps(FILE* f, FileOp* fop,
for (auto propertiesMap : propertiesMaps) {
const UserData::Properties& properties = propertiesMap.second;
// Skip properties map if it doesn't have any property
if (properties.size() == 0) continue;
if (properties.empty())
continue;
const std::string& extensionKey = propertiesMap.first;
try {
uint32_t extensionId = extensionKey == "" ? 0 : ext_files.to_id.at(extensionKey);
fputl(extensionId, f);
}
catch(const std::out_of_range&) {
ASSERT(false); // This shouldn't ever happen, but if it does...
// most likely it is because we forgot to add the
// extensionID to the ext_files object. And this
// Could happen if someone adds the possibility to
// store custom properties to some object that
// didn't support it previously.
uint32_t extensionId = 0;
if (!extensionKey.empty() &&
!ext_files.getIDByFilename(extensionKey, extensionId)) {
// This shouldn't ever happen, but if it does... most likely
// it is because we forgot to add the extensionID to the
// ext_files object. And this could happen if someone adds the
// possibility to store custom properties to some object that
// didn't support it previously.
ASSERT(false);
fop->setError("Error writing properties for extension '%s'.\n", extensionKey.c_str());
continue;
}
fputl(extensionId, f);
ase_file_write_properties(f, properties);
}
long endPos = ftell(f);

View File

@ -111,6 +111,7 @@ struct AsepriteExternalFiles {
std::map<uint32_t, uint8_t> types; // ID -> type (type has one of the ASE_EXTERNAL_FILE_* values)
uint32_t lastid = 0;
// Adds the external filename with the next autogenerated ID and specified type.
void put(const std::string& filename, uint8_t type) {
auto id = ++lastid;
@ -118,12 +119,31 @@ struct AsepriteExternalFiles {
to_id[filename] = id;
types[id] = type;
}
// Adds the external filename using the specified ID and type.
void put(uint32_t id, const std::string& filename, uint8_t type) {
to_fn[id] = filename;
to_id[filename] = id;
types[id] = type;
}
// Returns true if the given filename exists in the external files
// chunk, and assign its ID in "id"
bool getIDByFilename(const std::string& fn, uint32_t& id) const {
auto it = to_id.find(fn);
if (it == to_id.end())
return false;
id = it->second;
return true;
}
bool getFilenameByID(uint32_t id, std::string& fn) const {
auto it = to_fn.find(id);
if (it == to_fn.end())
return false;
fn = it->second;
return true;
}
};
} // namespace dio

View File

@ -1248,18 +1248,14 @@ void AsepriteDecoder::readPropertiesMaps(doc::UserData::PropertiesMaps& properti
auto numMaps = read32();
for (int i=0; i<numMaps; ++i) {
auto id = read32();
std::string extensionId = "";
if (id) {
try {
extensionId = extFiles.to_fn.at(id);
}
catch (const std::out_of_range&) {
// This shouldn't happen, but if it does, we put the properties
// in an artificial extensionId.
extensionId = fmt::format("__missed__{}", id);
delegate()->error(
fmt::format("Error: Invalid extension ID (id={0} not found)", id));
}
std::string extensionId; // extensionId = empty by default (when id == 0)
if (id &&
!extFiles.getFilenameByID(id, extensionId)) {
// This shouldn't happen, but if it does, we put the properties
// in an artificial extensionId.
extensionId = fmt::format("__missed__{}", id);
delegate()->error(
fmt::format("Error: Invalid extension ID (id={0} not found)", id));
}
auto properties = readPropertyValue(USER_DATA_PROPERTY_TYPE_PROPERTIES);
propertiesMaps[extensionId] = *std::get_if<doc::UserData::Properties>(&properties);