change char[] to std::string as svg file data storage

This commit is contained in:
Filip Sykala - NTB T15p 2023-09-06 13:46:49 +02:00
parent 41f1c2caa5
commit fc11639679
5 changed files with 33 additions and 68 deletions

View File

@ -100,7 +100,7 @@ struct EmbossShape
std::shared_ptr<NSVGimage> image = nullptr;
// Loaded string data from file
std::shared_ptr<char[]> file_data = nullptr;
std::shared_ptr<std::string> file_data = nullptr;
};
SvgFile svg_file;

View File

@ -474,7 +474,7 @@ namespace Slic3r {
typedef std::map<int, CutObjectInfo> IdToCutObjectInfoMap;
typedef std::map<int, std::vector<sla::SupportPoint>> IdToSlaSupportPointsMap;
typedef std::map<int, std::vector<sla::DrainHole>> IdToSlaDrainHolesMap;
using PathToEmbossShapeFileMap = std::map<std::string, std::shared_ptr<char[]>>;
using PathToEmbossShapeFileMap = std::map<std::string, std::shared_ptr<std::string>>;
// Version of the 3mf file
unsigned int m_version;
bool m_check_version;
@ -1387,25 +1387,18 @@ namespace Slic3r {
void _3MF_Importer::_extract_embossed_svg_shape_file(const std::string &filename, mz_zip_archive &archive, const mz_zip_archive_file_stat &stat){
assert(m_path_to_emboss_shape_files.find(filename) == m_path_to_emboss_shape_files.end());
std::unique_ptr<char[]> file{new char[stat.m_uncomp_size + 1]};
if (file == nullptr){
add_error("Cannot alocate space for SVG file.");
return;
}
mz_bool res = mz_zip_reader_extract_to_mem(&archive, stat.m_file_index, (void *) file.get(), (size_t) stat.m_uncomp_size, 0);
auto file = std::make_unique<std::string>(stat.m_uncomp_size, '\0');
mz_bool res = mz_zip_reader_extract_to_mem(&archive, stat.m_file_index, (void *) file->data(), stat.m_uncomp_size, 0);
if (res == 0) {
add_error("Error while reading svg shape for emboss");
return;
}
file.get()[stat.m_uncomp_size] = '\0'; // Must be null terminated.
// store for case svg is loaded before volume
m_path_to_emboss_shape_files[filename] = std::move(file);
// find embossed volume, for case svg is loaded after volume
for (ModelObject* object : m_model->objects)
for (const ModelObject* object : m_model->objects)
for (ModelVolume *volume : object->volumes) {
std::optional<EmbossShape> &es = volume->emboss_shape;
if (!es.has_value())
@ -3752,15 +3745,8 @@ bool to_xml(std::stringstream &stream, const EmbossShape::SvgFile &svg, const Mo
stream << SVG_FILE_PATH_ATTR << "=\"" << xml_escape_double_quotes_attribute_value(svg.path) << "\" ";
stream << SVG_FILE_PATH_IN_3MF_ATTR << "=\"" << xml_escape_double_quotes_attribute_value(svg.path_in_3mf) << "\" ";
char *data = svg.file_data.get();
assert(data != nullptr);
if (data == nullptr)
return false;
// NOTE: file data must be null terminated
size_t size = 0;
for (char *c = data; *c != '\0'; ++c) ++size;
if (!mz_zip_writer_add_mem(&archive, svg.path_in_3mf.c_str(), (const void *) data, size, MZ_DEFAULT_COMPRESSION))
const std::string &file_data = *svg.file_data;
if (!mz_zip_writer_add_mem(&archive, svg.path_in_3mf.c_str(), (const void *) file_data.c_str(), file_data.size(), MZ_DEFAULT_COMPRESSION))
return false;
return true;
}

View File

@ -98,41 +98,28 @@ void bounds(const NSVGimage &image, Vec2f& min, Vec2f &max)
NSVGimage_ptr nsvgParseFromFile(const std::string &filename, const char *units, float dpi)
{
NSVGimage *image = ::nsvgParseFromFile(filename.c_str(), units, dpi);
return {image, ::nsvgDelete};
return {image, &nsvgDelete};
}
std::unique_ptr<char[]> read_from_disk(const std::string& path)
std::unique_ptr<std::string> read_from_disk(const std::string &path)
{
FILE *fp = boost::nowide::fopen(path.c_str(), "rb");
if (!fp)
std::ifstream fs{path};
if (!fs.is_open())
return nullptr;
fseek(fp, 0, SEEK_END);
size_t size = ftell(fp);
fseek(fp, 0, SEEK_SET);
std::unique_ptr<char[]> result{new char[size + 1]};
if (result == nullptr)
return nullptr;
if (fread(result.get(), 1, size, fp) != size)
return nullptr;
result.get()[size] = '\0'; // Must be null terminated.
fclose(fp);
return result;
std::stringstream ss;
ss << fs.rdbuf();
return std::make_unique<std::string>(ss.str());
}
NSVGimage_ptr nsvgParse(const std::shared_ptr<char[]> file_data, const char *units, float dpi){
size_t size = 0;
for (char *c = file_data.get(); *c != '\0'; ++c)
++size;
// NOTE: nsvg parser consume data from pointer
std::unique_ptr<char[]> data_copy(new char[size]);
memcpy(data_copy.get(), file_data.get(), size);
NSVGimage_ptr nsvgParse(const std::string& file_data, const char *units, float dpi){
// NOTE: nsvg parser consume data from input(char *)
size_t size = file_data.size();
// file data could be big, so it is allocated on heap
std::unique_ptr<char[]> data_copy(new char[size+1]);
memcpy(data_copy.get(), file_data.c_str(), size);
data_copy[size] = '\0'; // data for nsvg must be null terminated
NSVGimage *image = ::nsvgParse(data_copy.get(), units, dpi);
return {image, ::nsvgDelete};
return {image, &nsvgDelete};
}
size_t get_shapes_count(const NSVGimage &image)

View File

@ -66,11 +66,11 @@ Polygons to_polygons(const NSVGimage &image, const NSVGLineParams &param);
void bounds(const NSVGimage &image, Vec2f &min, Vec2f &max);
// read text data from file
std::unique_ptr<char[]> read_from_disk(const std::string &path);
std::unique_ptr<std::string> read_from_disk(const std::string &path);
using NSVGimage_ptr = std::unique_ptr<NSVGimage, void (*)(NSVGimage*)>;
NSVGimage_ptr nsvgParseFromFile(const std::string &svg_file_path, const char *units = "mm", float dpi = 96.0f);
NSVGimage_ptr nsvgParse(const std::shared_ptr<char[]> file_data, const char *units = "mm", float dpi = 96.0f);
NSVGimage_ptr nsvgParse(const std::string& file_data, const char *units = "mm", float dpi = 96.0f);
/// <summary>
/// Iterate over shapes and calculate count

View File

@ -570,7 +570,7 @@ NSVGimage* init_image(EmbossShape::SvgFile &svg_file) {
}
// init svg image
svg_file.image = nsvgParse(svg_file.file_data);
svg_file.image = nsvgParse(*svg_file.file_data);
if (svg_file.image.get() == NULL)
return nullptr;
@ -1375,20 +1375,13 @@ void GLGizmoSVG::draw_filename(){
EmbossShape::SvgFile &svg = m_volume_shape.svg_file;
std::stringstream ss;
Slic3r::save(*svg.image, ss);
ss << '\0'; // Must be null terminated.
std::string str = ss.str();
std::unique_ptr<char[]> new_data{new char[str.size() + 1]};
assert(new_data != nullptr);
if (new_data != nullptr) {
std::copy(str.begin(), str.end(), new_data.get());
svg.file_data = std::move(new_data);
svg.image = nsvgParse(svg.file_data);
assert(svg.image.get() != NULL);
if (svg.image.get() != NULL) {
m_volume->emboss_shape->svg_file = svg; // copy - write changes into volume
} else {
svg = m_volume->emboss_shape->svg_file; // revert changes
}
svg.file_data = std::make_unique<std::string>(ss.str());
svg.image = nsvgParse(*svg.file_data);
assert(svg.image.get() != NULL);
if (svg.image.get() != NULL) {
m_volume->emboss_shape->svg_file = svg; // copy - write changes into volume
} else {
svg = m_volume->emboss_shape->svg_file; // revert changes
}
} else if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("%s", _u8L("Use only paths from svg - recreate svg").c_str());
@ -2000,8 +1993,7 @@ EmbossShape select_shape(std::string_view filepath, double tesselation_tolerance
return {};
}
init_image(shape.svg_file);
if (shape.svg_file.image.get() == NULL) {
if(init_image(shape.svg_file) == nullptr) {
show_error(nullptr, GUI::format(_u8L("Nano SVG parser can't load from file(%1%)."), shape.svg_file.path));
return {};
}