core: convert save-xml.c to C++

This includes using the C++ version of membuffer. There appears
to not have been a leak, because the buffer is freed in
flush_buffer(), but usage was somewhat inconsistent and hard to
follow.

Also, convert some string handling to std::string to avoid free()
madness.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2024-02-28 06:36:48 +01:00
parent be3a497885
commit b060df91e7
3 changed files with 30 additions and 46 deletions

View file

@ -82,7 +82,7 @@ SOURCES += subsurface-mobile-main.cpp \
core/datatrak.c \
core/ostctools.c \
core/planner.c \
core/save-xml.c \
core/save-xml.cpp \
core/cochran.c \
core/deco.c \
core/divesite.c \

View file

@ -159,7 +159,7 @@ set(SUBSURFACE_CORE_LIB_SRCS
save-html.c
save-html.h
save-profiledata.c
save-xml.c
save-xml.cpp
selection.cpp
selection.h
sha1.c

View file

@ -54,7 +54,6 @@ static void quote(struct membuffer *b, const char *text, int is_attribute)
static void show_utf8(struct membuffer *b, const char *text, const char *pre, const char *post, int is_attribute)
{
int len;
char *cleaned;
if (!text)
return;
@ -69,27 +68,25 @@ static void show_utf8(struct membuffer *b, const char *text, const char *pre, co
return;
while (len && isascii(text[len - 1]) && isspace(text[len - 1]))
len--;
cleaned = strndup(text, len);
std::string cleaned(text, len);
put_string(b, pre);
quote(b, cleaned, is_attribute);
quote(b, cleaned.c_str(), is_attribute);
put_string(b, post);
free(cleaned);
}
static void blankout(char *c)
static void blankout(std::string &s)
{
while(*c) {
switch (*c) {
for(char &c: s) {
switch (c) {
case 'A'...'Z':
*c = 'X';
c = 'X';
break;
case 'a'...'z':
*c = 'x';
c = 'x';
break;
default:
;
}
++c;
}
}
@ -97,12 +94,11 @@ static void show_utf8_blanked(struct membuffer *b, const char *text, const char
{
if (!text)
return;
char *copy = strdup(text);
std::string copy(text);
if (anonymize)
blankout(copy);
show_utf8(b, copy, pre, post, is_attribute);
free(copy);
show_utf8(b, copy.c_str(), pre, post, is_attribute);
}
static void save_depths(struct membuffer *b, struct divecomputer *dc)
@ -432,7 +428,7 @@ static void save_samples(struct membuffer *b, struct dive *dive, struct divecomp
int nr;
int o2sensor;
struct sample *s;
struct sample dummy = { .bearing.degrees = -1, .ndl.seconds = -1 };
struct sample dummy;
/* Set up default pressure sensor indices */
o2sensor = legacy_format_o2pressures(dive, dc);
@ -464,9 +460,9 @@ static void save_dc(struct membuffer *b, struct dive *dive, struct divecomputer
if (dc->duration.seconds && dc->duration.seconds != dive->dc.duration.seconds)
put_duration(b, dc->duration, " duration='", " min'");
if (dc->divemode != OC) {
for (enum divemode_t i = 0; i < NUM_DIVEMODE; i++)
if (dc->divemode == i)
show_utf8(b, divemode_text[i], " dctype='", "'", 1);
int i = (int)dc->divemode;
if (i >= 0 && i < NUM_DIVEMODE)
show_utf8(b, divemode_text[i], " dctype='", "'", 1);
if (dc->no_o2sensors)
put_format(b," no_o2sensors='%d'", dc->no_o2sensors);
}
@ -502,7 +498,7 @@ static void save_picture(struct membuffer *b, struct picture *pic)
put_string(b, "/>\n");
}
void save_one_dive_to_mb(struct membuffer *b, struct dive *dive, bool anonymize)
extern "C" void save_one_dive_to_mb(struct membuffer *b, struct dive *dive, bool anonymize)
{
struct divecomputer *dc;
pressure_t surface_pressure = un_fixup_surface_pressure(dive);
@ -561,9 +557,9 @@ void save_one_dive_to_mb(struct membuffer *b, struct dive *dive, bool anonymize)
put_format(b, "</dive>\n");
}
int save_dive(FILE *f, struct dive *dive, bool anonymize)
extern "C" int save_dive(FILE *f, struct dive *dive, bool anonymize)
{
struct membuffer buf = { 0 };
struct membufferpp buf;
save_one_dive_to_mb(&buf, dive, anonymize);
flush_buffer(&buf, f);
@ -634,7 +630,7 @@ static void save_one_fingerprint(struct membuffer *b, int i)
free(data);
}
int save_dives(const char *filename)
extern "C" int save_dives(const char *filename)
{
return save_dives_logic(filename, false, false);
}
@ -780,8 +776,7 @@ static void save_dives_buffer(struct membuffer *b, bool select_only, bool anonym
static void save_backup(const char *name, const char *ext, const char *new_ext)
{
int len = strlen(name);
int a = strlen(ext), b = strlen(new_ext);
char *newname;
int a = strlen(ext);
/* len up to and including the final '.' */
len -= a;
@ -793,20 +788,15 @@ static void save_backup(const char *name, const char *ext, const char *new_ext)
if (strncasecmp(name + len, ext, a))
return;
newname = malloc(len + b + 1);
if (!newname)
return;
memcpy(newname, name, len);
memcpy(newname + len, new_ext, b + 1);
std::string newname(name, len);
newname += new_ext;
/*
* Ignore errors. Maybe we can't create the backup file,
* maybe no old file existed. Regardless, we'll write the
* new file.
*/
(void) subsurface_rename(name, newname);
free(newname);
(void) subsurface_rename(name, newname.c_str());
}
static void try_to_backup(const char *filename)
@ -820,11 +810,8 @@ static void try_to_backup(const char *filename)
int elen = strlen(extension[i]);
if (strcasecmp(filename + flen - elen, extension[i]) == 0) {
if (last_xml_version < DATAFORMAT_VERSION) {
int se_len = strlen(extension[i]) + 5;
char *special_ext = malloc(se_len);
snprintf(special_ext, se_len, "%s.v%d", extension[i], last_xml_version);
save_backup(filename, extension[i], special_ext);
free(special_ext);
std::string special_ext = std::string(extension[i]) + ".v" + std::to_string(last_xml_version);
save_backup(filename, extension[i], special_ext.c_str());
} else {
save_backup(filename, extension[i], "bak");
}
@ -834,9 +821,9 @@ static void try_to_backup(const char *filename)
}
}
int save_dives_logic(const char *filename, const bool select_only, bool anonymize)
extern "C" int save_dives_logic(const char *filename, const bool select_only, bool anonymize)
{
struct membuffer buf = { 0 };
struct membufferpp buf;
struct git_info info;
FILE *f;
int error = 0;
@ -863,7 +850,6 @@ int save_dives_logic(const char *filename, const bool select_only, bool anonymiz
if (error)
report_error(translate("gettextFromC", "Failed to save dives to %s (%s)"), filename, strerror(errno));
free_buffer(&buf);
return error;
}
@ -880,7 +866,7 @@ int export_dives_xslt(const char *filename, const bool selected, const int units
static int export_dives_xslt_doit(const char *filename, struct xml_params *params, bool selected, int units, const char *export_xslt, bool anonymize)
{
FILE *f;
struct membuffer buf = { 0 };
struct membufferpp buf;
xmlDoc *doc;
xsltStylesheetPtr xslt = NULL;
xmlDoc *transformed;
@ -901,7 +887,6 @@ static int export_dives_xslt_doit(const char *filename, struct xml_params *param
* the XML into a character buffer.
*/
doc = xmlReadMemory(buf.buffer, buf.len, "divelog", NULL, XML_PARSE_HUGE | XML_PARSE_RECOVER);
free_buffer(&buf);
if (!doc)
return report_error("Failed to read XML memory");
@ -961,9 +946,9 @@ static void save_dive_sites_buffer(struct membuffer *b, const struct dive_site *
put_format(b, "</divesites>\n");
}
int save_dive_sites_logic(const char *filename, const struct dive_site *sites[], int nr_sites, bool anonymize)
extern "C" int save_dive_sites_logic(const char *filename, const struct dive_site *sites[], int nr_sites, bool anonymize)
{
struct membuffer buf = { 0 };
struct membufferpp buf;
FILE *f;
int error = 0;
@ -983,6 +968,5 @@ int save_dive_sites_logic(const char *filename, const struct dive_site *sites[],
if (error)
report_error(translate("gettextFromC", "Failed to save divesites to %s (%s)"), filename, strerror(errno));
free_buffer(&buf);
return error;
}