1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 04:57:45 +00:00

AK+Spreadsheet+LibWeb: Remove JsonObject::get_or()

This removes JsonObject::get_or(), which is inefficient because it has
to copy the returned value. It was only used in a few cases, some of
which resulted in copying JsonObjects, which can become quite large.
This commit is contained in:
Max Wipfli 2021-06-28 12:40:04 +02:00 committed by Andreas Kling
parent e82611bb87
commit 9c8a2a5f69
4 changed files with 91 additions and 97 deletions

View file

@ -343,10 +343,8 @@ RefPtr<Sheet> Sheet::from_json(const JsonObject& object, Workbook& workbook)
auto rows = object.get("rows").to_u32(default_row_count);
auto columns = object.get("columns");
auto name = object.get("name").as_string_or("Sheet");
auto cells_value = object.get_or("cells", JsonObject {});
if (!cells_value.is_object())
return nullptr;
auto& cells = cells_value.as_object();
if (object.has("cells") && !object.has_object("cells"))
return {};
sheet->set_name(name);
@ -376,77 +374,79 @@ RefPtr<Sheet> Sheet::from_json(const JsonObject& object, Workbook& workbook)
format.background_color = Color::from_string(value.as_string());
};
cells.for_each_member([&](auto& name, JsonValue const& value) {
auto position_option = sheet->parse_cell_name(name);
if (!position_option.has_value())
return IterationDecision::Continue;
auto position = position_option.value();
auto& obj = value.as_object();
auto kind = obj.get("kind").as_string_or("LiteralString") == "LiteralString" ? Cell::LiteralString : Cell::Formula;
OwnPtr<Cell> cell;
switch (kind) {
case Cell::LiteralString:
cell = make<Cell>(obj.get("value").to_string(), position, *sheet);
break;
case Cell::Formula: {
auto& interpreter = sheet->interpreter();
auto value = interpreter.vm().call(parse_function, json, JS::js_string(interpreter.heap(), obj.get("value").as_string()));
cell = make<Cell>(obj.get("source").to_string(), move(value), position, *sheet);
break;
}
}
auto type_name = obj.get_or("type", "Numeric").to_string();
cell->set_type(type_name);
auto type_meta = obj.get("type_metadata");
if (type_meta.is_object()) {
auto& meta_obj = type_meta.as_object();
auto meta = cell->type_metadata();
if (auto value = meta_obj.get("length"); value.is_number())
meta.length = value.to_i32();
if (auto value = meta_obj.get("format"); value.is_string())
meta.format = value.as_string();
read_format(meta.static_format, meta_obj);
cell->set_type_metadata(move(meta));
}
auto conditional_formats = obj.get("conditional_formats");
auto cformats = cell->conditional_formats();
if (conditional_formats.is_array()) {
conditional_formats.as_array().for_each([&](const auto& fmt_val) {
if (!fmt_val.is_object())
return IterationDecision::Continue;
auto& fmt_obj = fmt_val.as_object();
auto fmt_cond = fmt_obj.get("condition").to_string();
if (fmt_cond.is_empty())
return IterationDecision::Continue;
ConditionalFormat fmt;
fmt.condition = move(fmt_cond);
read_format(fmt, fmt_obj);
cformats.append(move(fmt));
if (object.has_object("cells")) {
object.get("cells").as_object().for_each_member([&](auto& name, JsonValue const& value) {
auto position_option = sheet->parse_cell_name(name);
if (!position_option.has_value())
return IterationDecision::Continue;
});
cell->set_conditional_formats(move(cformats));
}
auto evaluated_format = obj.get("evaluated_formats");
if (evaluated_format.is_object()) {
auto& evaluated_format_obj = evaluated_format.as_object();
auto& evaluated_fmts = cell->evaluated_formats();
auto position = position_option.value();
auto& obj = value.as_object();
auto kind = obj.get("kind").as_string_or("LiteralString") == "LiteralString" ? Cell::LiteralString : Cell::Formula;
read_format(evaluated_fmts, evaluated_format_obj);
}
OwnPtr<Cell> cell;
switch (kind) {
case Cell::LiteralString:
cell = make<Cell>(obj.get("value").to_string(), position, *sheet);
break;
case Cell::Formula: {
auto& interpreter = sheet->interpreter();
auto value = interpreter.vm().call(parse_function, json, JS::js_string(interpreter.heap(), obj.get("value").as_string()));
cell = make<Cell>(obj.get("source").to_string(), move(value), position, *sheet);
break;
}
}
sheet->m_cells.set(position, cell.release_nonnull());
return IterationDecision::Continue;
});
auto type_name = obj.has("type") ? obj.get("type").to_string() : "Numeric";
cell->set_type(type_name);
auto type_meta = obj.get("type_metadata");
if (type_meta.is_object()) {
auto& meta_obj = type_meta.as_object();
auto meta = cell->type_metadata();
if (auto value = meta_obj.get("length"); value.is_number())
meta.length = value.to_i32();
if (auto value = meta_obj.get("format"); value.is_string())
meta.format = value.as_string();
read_format(meta.static_format, meta_obj);
cell->set_type_metadata(move(meta));
}
auto conditional_formats = obj.get("conditional_formats");
auto cformats = cell->conditional_formats();
if (conditional_formats.is_array()) {
conditional_formats.as_array().for_each([&](const auto& fmt_val) {
if (!fmt_val.is_object())
return IterationDecision::Continue;
auto& fmt_obj = fmt_val.as_object();
auto fmt_cond = fmt_obj.get("condition").to_string();
if (fmt_cond.is_empty())
return IterationDecision::Continue;
ConditionalFormat fmt;
fmt.condition = move(fmt_cond);
read_format(fmt, fmt_obj);
cformats.append(move(fmt));
return IterationDecision::Continue;
});
cell->set_conditional_formats(move(cformats));
}
auto evaluated_format = obj.get("evaluated_formats");
if (evaluated_format.is_object()) {
auto& evaluated_format_obj = evaluated_format.as_object();
auto& evaluated_fmts = cell->evaluated_formats();
read_format(evaluated_fmts, evaluated_format_obj);
}
sheet->m_cells.set(position, cell.release_nonnull());
return IterationDecision::Continue;
});
}
return sheet;
}