int save_dive(FILE *f, struct dive *dive) { struct membuffer buf = { 0 }; save_one_dive_to_mb(&buf, dive); flush_buffer(&buf, f); /* Error handling? */ return 0; }
static void save_trip(struct membuffer *b, dive_trip_t *trip) { int i; struct dive *dive; put_format(b, "<trip"); show_date(b, trip->when); show_utf8(b, trip->location, " location=\'", "\'", 1); put_format(b, ">\n"); show_utf8(b, trip->notes, "<notes>", "</notes>\n", 0); /* * Incredibly cheesy: we want to save the dives sorted, and they * are sorted in the dive array.. So instead of using the dive * list in the trip, we just traverse the global dive array and * check the divetrip pointer.. */ for_each_dive(i, dive) { if (dive->divetrip == trip) save_one_dive_to_mb(b, dive); } put_format(b, "</trip>\n"); }
// TODO: This looks like should be ported to C code. or a big part of it. bool DivelogsDeWebServices::prepare_dives_for_divelogs(const QString &tempfile, const bool selected) { static const char errPrefix[] = "divelog.de-upload:"; if (!amount_selected) { report_error(tr("no dives were selected").toUtf8()); return false; } xsltStylesheetPtr xslt = NULL; struct zip *zip; xslt = get_stylesheet("divelogs-export.xslt"); if (!xslt) { qDebug() << errPrefix << "missing stylesheet"; return false; } int error_code; zip = zip_open(QFile::encodeName(QDir::toNativeSeparators(tempfile)), ZIP_CREATE, &error_code); if (!zip) { char buffer[1024]; zip_error_to_str(buffer, sizeof buffer, error_code, errno); report_error(tr("failed to create zip file for upload: %s").toUtf8(), buffer); return false; } /* walk the dive list in chronological order */ int i; struct dive *dive; struct membuffer mb = { 0 }; for_each_dive (i, dive) { FILE *f; char filename[PATH_MAX]; int streamsize; const char *membuf; xmlDoc *transformed; struct zip_source *s; /* * Get the i'th dive in XML format so we can process it. * We need to save to a file before we can reload it back into memory... */ if (selected && !dive->selected) continue; /* make sure the buffer is empty and add the dive */ mb.len = 0; save_one_dive_to_mb(&mb, dive); membuf = mb_cstring(&mb); streamsize = strlen(membuf); /* * Parse the memory buffer into XML document and * transform it to divelogs.de format, finally dumping * the XML into a character buffer. */ xmlDoc *doc = xmlReadMemory(membuf, streamsize, "divelog", NULL, 0); if (!doc) { qWarning() << errPrefix << "could not parse back into memory the XML file we've just created!"; report_error(tr("internal error").toUtf8()); goto error_close_zip; } free((void *)membuf); transformed = xsltApplyStylesheet(xslt, doc, NULL); xmlDocDumpMemory(transformed, (xmlChar **)&membuf, &streamsize); xmlFreeDoc(doc); xmlFreeDoc(transformed); /* * Save the XML document into a zip file. */ snprintf(filename, PATH_MAX, "%d.xml", i + 1); s = zip_source_buffer(zip, membuf, streamsize, 1); if (s) { int64_t ret = zip_add(zip, filename, s); if (ret == -1) qDebug() << errPrefix << "failed to include dive:" << i; } }
void save_dives_buffer(struct membuffer *b, const bool select_only) { int i; struct dive *dive; dive_trip_t *trip; put_format(b, "<divelog program='subsurface' version='%d'>\n<settings>\n", VERSION); if (prefs.save_userid_local) put_format(b, " <userid>%30s</userid>\n", prefs.userid); /* save the dive computer nicknames, if any */ call_for_each_dc(b, save_one_device); if (autogroup) put_format(b, " <autogroup state='1' />\n"); put_format(b, "</settings>\n"); /* save the dive sites */ put_format(b, "<divesites>\n"); for (i = 0; i < dive_site_table.nr; i++) { struct dive_site *ds = get_dive_site(i); if (dive_site_is_empty(ds)) { int j; struct dive *d; for_each_dive(j, d) { if (d->dive_site_uuid == ds->uuid) d->dive_site_uuid = 0; } delete_dive_site(get_dive_site(i)->uuid); i--; // since we just deleted that one continue; } put_format(b, "<site uuid='%8x'", ds->uuid); show_utf8(b, ds->name, " name='", "'", 1); if (ds->latitude.udeg || ds->longitude.udeg) { put_degrees(b, ds->latitude, " gps='", " "); put_degrees(b, ds->longitude, "", "'"); } show_utf8(b, ds->description, " description='", "'", 1); show_utf8(b, ds->notes, " notes='", "'", 1); put_format(b, "/>\n"); } put_format(b, "</divesites>\n<dives>\n"); for (trip = dive_trip_list; trip != NULL; trip = trip->next) trip->index = 0; /* save the dives */ for_each_dive(i, dive) { if (select_only) { if (!dive->selected) continue; save_one_dive_to_mb(b, dive); } else { trip = dive->divetrip; /* Bare dive without a trip? */ if (!trip) { save_one_dive_to_mb(b, dive); continue; } /* Have we already seen this trip (and thus saved this dive?) */ if (trip->index) continue; /* We haven't seen this trip before - save it and all dives */ trip->index = 1; save_trip(b, trip); } } put_format(b, "</dives>\n</divelog>\n"); }
void save_dives_buffer(struct membuffer *b, const bool select_only) { int i; struct dive *dive; dive_trip_t *trip; put_format(b, "<divelog program='subsurface' version='%d'>\n<settings>\n", DATAFORMAT_VERSION); if (prefs.save_userid_local) put_format(b, " <userid>%30s</userid>\n", prefs.userid); /* save the dive computer nicknames, if any */ call_for_each_dc(b, save_one_device, select_only); if (autogroup) put_format(b, " <autogroup state='1' />\n"); put_format(b, "</settings>\n"); /* save the dive sites - to make the output consistent let's sort the table, first */ dive_site_table_sort(); put_format(b, "<divesites>\n"); for (i = 0; i < dive_site_table.nr; i++) { int j; struct dive *d; struct dive_site *ds = get_dive_site(i); if (dive_site_is_empty(ds)) { for_each_dive(j, d) { if (d->dive_site_uuid == ds->uuid) d->dive_site_uuid = 0; } delete_dive_site(get_dive_site(i)->uuid); i--; // since we just deleted that one continue; } if (select_only && !is_dive_site_used(ds->uuid, true)) continue; put_format(b, "<site uuid='%8x'", ds->uuid); show_utf8(b, ds->name, " name='", "'", 1); if (ds->latitude.udeg || ds->longitude.udeg) { put_degrees(b, ds->latitude, " gps='", " "); put_degrees(b, ds->longitude, "", "'"); } show_utf8(b, ds->description, " description='", "'", 1); show_utf8(b, ds->notes, " notes='", "'", 1); if (ds->taxonomy.nr) { put_format(b, ">\n"); for (int j = 0; j < ds->taxonomy.nr; j++) { struct taxonomy *t = &ds->taxonomy.category[j]; if (t->category != TC_NONE) { put_format(b, "<geo cat='%d'", t->category); put_format(b, " origin='%d'", t->origin); show_utf8(b, t->value, " value='", "'/>\n", 1); } } put_format(b, "</site>\n"); } else { put_format(b, "/>\n"); } } put_format(b, "</divesites>\n<dives>\n"); for (trip = dive_trip_list; trip != NULL; trip = trip->next) trip->index = 0; /* save the dives */ for_each_dive(i, dive) { if (select_only) { if (!dive->selected) continue; save_one_dive_to_mb(b, dive); } else { trip = dive->divetrip; /* Bare dive without a trip? */ if (!trip) { save_one_dive_to_mb(b, dive); continue; } /* Have we already seen this trip (and thus saved this dive?) */ if (trip->index) continue; /* We haven't seen this trip before - save it and all dives */ trip->index = 1; save_trip(b, trip); } } put_format(b, "</dives>\n</divelog>\n"); }