コード例 #1
0
ファイル: save-xml.c プロジェクト: pidancier/subsurface
int save_dives_logic(const char *filename, const bool select_only)
{
	struct membuffer buf = { 0 };
	FILE *f;
	void *git;
	const char *branch;
	int error;

	git = is_git_repository(filename, &branch);
	if (git)
		return git_save_dives(git, branch, select_only);

	try_to_backup(filename);

	save_dives_buffer(&buf, select_only);

	error = -1;
	f = subsurface_fopen(filename, "w");
	if (f) {
		flush_buffer(&buf, f);
		error = fclose(f);
	}
	if (error)
		report_error("Save failed (%s)", strerror(errno));

	free_buffer(&buf);
	return error;
}
コード例 #2
0
ファイル: save-xml.c プロジェクト: pidancier/subsurface
int export_dives_xslt(const char *filename, const bool selected, const int units, const char *export_xslt)
{
	FILE *f;
	struct membuffer buf = { 0 };
	xmlDoc *doc;
	xsltStylesheetPtr xslt = NULL;
	xmlDoc *transformed;
	int res = 0;
	char *params[3];
	int pnr = 0;
	char unitstr[3];

	if (verbose)
		fprintf(stderr, "export_dives_xslt with stylesheet %s\n", export_xslt);

	if (!filename)
		return report_error("No filename for export");

	/* Save XML to file and convert it into a memory buffer */
	save_dives_buffer(&buf, selected);

	/*
	 * Parse the memory buffer into XML document and
	 * transform it to selected export format, finally dumping
	 * the XML into a character buffer.
	 */
	doc = xmlReadMemory(buf.buffer, buf.len, "divelog", NULL, 0);
	free_buffer(&buf);
	if (!doc)
		return report_error("Failed to read XML memory");

	/* Convert to export format */
	xslt = get_stylesheet(export_xslt);
	if (!xslt)
		return report_error("Failed to open export conversion stylesheet");

	snprintf(unitstr, 3, "%d", units);
	params[pnr++] = "units";
	params[pnr++] = unitstr;
	params[pnr++] = NULL;

	transformed = xsltApplyStylesheet(xslt, doc, (const char **)params);
	xmlFreeDoc(doc);

	/* Write the transformed export to file */
	f = subsurface_fopen(filename, "w");
	if (f) {
		xsltSaveResultToFile(f, transformed, xslt);
		fclose(f);
		/* Check write errors? */
	} else {
		res = report_error("Failed to open %s for writing (%s)", filename, strerror(errno));
	}
	xsltFreeStylesheet(xslt);
	xmlFreeDoc(transformed);

	return res;
}
コード例 #3
0
ファイル: save-xml.c プロジェクト: joscandreu/subsurface
int export_dives_xslt(const char *filename, const bool selected, const char *export_xslt)
{
	FILE *f;
	struct membuffer buf = { 0 };
	xmlDoc *doc;
	xsltStylesheetPtr xslt = NULL;
	xmlDoc *transformed;


	if (!filename)
		return report_error("No filename for export");

	/* Save XML to file and convert it into a memory buffer */
	save_dives_buffer(&buf, selected);

	/*
	 * Parse the memory buffer into XML document and
	 * transform it to selected export format, finally dumping
	 * the XML into a character buffer.
	 */
	doc = xmlReadMemory(buf.buffer, buf.len, "divelog", NULL, 0);
	free_buffer(&buf);
	if (!doc)
		return report_error("Failed to read XML memory");

	/* Convert to export format */
	xslt = get_stylesheet(export_xslt);
	if (!xslt)
		return report_error("Failed to open export conversion stylesheet");

	transformed = xsltApplyStylesheet(xslt, doc, NULL);
	xsltFreeStylesheet(xslt);
	xmlFreeDoc(doc);

	/* Write the transformed export to file */
	f = subsurface_fopen(filename, "w");
	if (!f)
		return report_error("Failed to open %s for writing (%s)", filename, strerror(errno));

	xmlDocFormatDump(f, transformed, 1);
	xmlFreeDoc(transformed);

	fclose(f);
	/* Check write errors? */
	return 0;
}
コード例 #4
0
QString ConfigureDiveComputer::dc_open(device_data_t *data)
{
	FILE *fp = NULL;
	dc_status_t rc;

	if (data->libdc_log)
		fp = subsurface_fopen(logfile_name, "w");

	data->libdc_logfile = fp;

	rc = dc_context_new(&data->context);
	if (rc != DC_STATUS_SUCCESS) {
		return tr("Unable to create libdivecomputer context");
	}

	if (fp) {
		dc_context_set_loglevel(data->context, DC_LOGLEVEL_ALL);
		dc_context_set_logfunc(data->context, logfunc, fp);
		fprintf(data->libdc_logfile, "Subsurface: v%s, ", subsurface_git_version());
		fprintf(data->libdc_logfile, "built with libdivecomputer v%s\n", dc_version(NULL));
	}

	rc = divecomputer_device_open(data);

	if (rc != DC_STATUS_SUCCESS) {
		report_error(errmsg(rc));
	} else {
		rc = dc_device_open(&data->device, data->context, data->descriptor, data->iostream);
	}

	if (rc != DC_STATUS_SUCCESS) {
		return tr("Could not a establish connection to the dive computer.");
	}

	setState(OPEN);

	return NULL;
}
コード例 #5
0
void DiveLogExportDialog::export_depths(const char *filename, const bool selected_only)
{
	FILE *f;
	struct dive *dive;
	depth_t depth;
	int i;
	const char *unit = NULL;

	struct membuffer buf = {};

	for_each_dive (i, dive) {
		if (selected_only && !dive->selected)
			continue;

		FOR_EACH_PICTURE (dive) {
			int n = dive->dc.samples;
			struct sample *s = dive->dc.sample;
			depth.mm = 0;
			while (--n >= 0 && (int32_t)s->time.seconds <= picture->offset.seconds) {
				depth.mm = s->depth.mm;
				s++;
			}
			put_format(&buf, "%s\t%.1f", picture->filename, get_depth_units(depth.mm, NULL, &unit));
			put_format(&buf, "%s\n", unit);
		}
	}

	f = subsurface_fopen(filename, "w+");
	if (!f) {
		report_error(tr("Can't open file %s").toUtf8().data(), filename);
	} else {
		flush_buffer(&buf, f); /*check for writing errors? */
		fclose(f);
	}
	free_buffer(&buf);
}
コード例 #6
0
ファイル: ostctools.c プロジェクト: Brainiarc7/subsurface
/*
 * OSTCTools stores the raw dive data in heavily padded files, one dive
 * each file. So it's not necessary to iterate once and again on a parsing
 * function. Actually there's only one kind of archive for every DC model.
 */
void ostctools_import(const char *file, struct dive_table *divetable)
{
	FILE *archive;
	device_data_t *devdata = calloc(1, sizeof(device_data_t));
	dc_family_t dc_fam;
	unsigned char *buffer = calloc(65536, 1), *uc_tmp;
	char *tmp;
	struct dive *ostcdive = alloc_dive();
	dc_status_t rc = 0;
	int model, ret, i = 0;
	unsigned int serial;
	struct extra_data *ptr;

	// Open the archive
	if ((archive = subsurface_fopen(file, "rb")) == NULL) {
		report_error(translate("gettextFromC", "Failed to read '%s'"), file);
		free(ostcdive);
		goto out;
	}

	// Read dive number from the log
	uc_tmp = calloc(2, 1);
	fseek(archive, 258, 0);
	fread(uc_tmp, 1, 2, archive);
	ostcdive->number = uc_tmp[0] + (uc_tmp[1] << 8);
	free(uc_tmp);

	// Read device's serial number
	uc_tmp = calloc(2, 1);
	fseek(archive, 265, 0);
	fread(uc_tmp, 1, 2, archive);
	serial = uc_tmp[0] + (uc_tmp[1] << 8);
	free(uc_tmp);

	// Read dive's raw data, header + profile
	fseek(archive, 456, 0);
	while (!feof(archive)) {
		fread(buffer + i, 1, 1, archive);
		if (buffer[i] == 0xFD && buffer[i - 1] == 0xFD)
			break;
		i++;
	}

	// Try to determine the dc family based on the header type
	if (buffer[2] == 0x20 || buffer[2] == 0x21) {
		dc_fam = DC_FAMILY_HW_OSTC;
	} else {
		switch (buffer[8]) {
		case 0x22:
			dc_fam = DC_FAMILY_HW_FROG;
			break;
		case 0x23:
			dc_fam = DC_FAMILY_HW_OSTC3;
			break;
		default:
			report_error(translate("gettextFromC", "Unknown DC in dive %d"), ostcdive->number);
			free(ostcdive);
			fclose(archive);
			goto out;
		}
	}

	// Try to determine the model based on serial number
	switch (dc_fam) {
	case DC_FAMILY_HW_OSTC:
		if (serial > 7000)
			model = 3; //2C
		else if (serial > 2048)
			model = 2; //2N
		else if (serial > 300)
			model = 1; //MK2
		else
			model = 0; //OSTC
		break;
	case DC_FAMILY_HW_FROG:
		model = 0;
		break;
	default:
		if (serial > 10000)
			model = 0x12; //Sport
		else
			model = 0x0A; //OSTC3
	}

	// Prepare data to pass to libdivecomputer.
	ret = ostc_prepare_data(model, dc_fam, devdata);
	if (ret == 0) {
		report_error(translate("gettextFromC", "Unknown DC in dive %d"), ostcdive->number);
		free(ostcdive);
		fclose(archive);
		goto out;
	}
	tmp = calloc(strlen(devdata->vendor) + strlen(devdata->model) + 28, 1);
	sprintf(tmp, "%s %s (Imported from OSTCTools)", devdata->vendor, devdata->model);
	ostcdive->dc.model = copy_string(tmp);
	free(tmp);

	// Parse the dive data
	rc = libdc_buffer_parser(ostcdive, devdata, buffer, i + 1);
	if (rc != DC_STATUS_SUCCESS)
		report_error(translate("gettextFromC", "Error - %s - parsing dive %d"), errmsg(rc), ostcdive->number);

	// Serial number is not part of the header nor the profile, so libdc won't
	// catch it. If Serial is part of the extra_data, and set to zero, remove
	// it from the list and add again.
	tmp = calloc(12, 1);
	sprintf(tmp, "%d", serial);
	ostcdive->dc.serial = copy_string(tmp);
	free(tmp);

	if (ostcdive->dc.extra_data) {
		ptr = ostcdive->dc.extra_data;
		while (strcmp(ptr->key, "Serial"))
			ptr = ptr->next;
		if (!strcmp(ptr->value, "0")) {
			add_extra_data(&ostcdive->dc, "Serial", ostcdive->dc.serial);
			*ptr = *(ptr)->next;
		}
	} else {
		add_extra_data(&ostcdive->dc, "Serial", ostcdive->dc.serial);
	}
	record_dive_to_table(ostcdive, divetable);
	mark_divelist_changed(true);
	sort_table(divetable);
	fclose(archive);
out:
	free(devdata);
	free(buffer);
}
コード例 #7
0
// 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;
	for_each_dive (i, dive) {
		FILE *f;
		char filename[PATH_MAX];
		int streamsize;
		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;
		QString innerTmpFile = tempfile;
		QString tmpSuffix = QString::number(qrand() % 9999) + ".tmp";
		innerTmpFile.replace(".dld", tmpSuffix);
		f = subsurface_fopen(QFile::encodeName(QDir::toNativeSeparators(innerTmpFile)), "w+");
		if (!f) {
			report_error(tr("cannot create temporary file: %s").toUtf8(), qt_error_string().toUtf8().data());
			goto error_close_zip;
		}
		save_dive(f, dive);
		fseek(f, 0, SEEK_END);
		streamsize = ftell(f);
		rewind(f);

		membuf = (char *)malloc(streamsize + 1);
		if (!membuf || (streamsize = fread(membuf, 1, streamsize, f)) == 0) {
			report_error(tr("internal error: %s").toUtf8(), qt_error_string().toUtf8().data());
			fclose(f);
			free((void *)membuf);
			goto error_close_zip;
		}
		membuf[streamsize] = 0;
		fclose(f);
		unlink(QFile::encodeName(QDir::toNativeSeparators(innerTmpFile)));
		/*
		 * 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());
			free((void *)membuf);
			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;
		}
	}
コード例 #8
0
ファイル: ostctools.c プロジェクト: gordonpeterson/subsurface
/*
 * OSTCTools stores the raw dive data in heavily padded files, one dive
 * each file. So it's not necesary to iterate once and again on a parsing
 * function. Actually there's only one kind of archive for every DC model.
 */
void ostctools_import(const char *file, struct dive_table *divetable)
{
	FILE *archive;
	device_data_t *devdata = calloc(1, sizeof(device_data_t));
	dc_family_t dc_fam;
	unsigned char *buffer = calloc(65536, 1),
		      *tmp;
	struct dive *ostcdive = alloc_dive();
	dc_status_t rc = 0;
	int model = 0, i = 0;
	unsigned int serial;
	struct extra_data *ptr;

	// Open the archive
	if ((archive = subsurface_fopen(file, "rb")) == NULL) {
		report_error(translate("gettextFromC", "Error: couldn't open the file"));
		return;
	}

	// Read dive number from the log
	tmp =  calloc(2,1);
	fseek(archive, 258, 0);
	fread(tmp, 1, 2, archive);
	ostcdive->number = tmp[0] + (tmp[1] << 8);
	free(tmp);

	// Read device's serial number
	tmp = calloc(2, 1);
	fseek(archive, 265, 0);
	fread(tmp, 1, 2, archive);
	serial = tmp[0] + (tmp[1] << 8);
	free(tmp);

	// Read dive's raw data, header + profile
	fseek(archive, 456, 0);
	while (!feof(archive)) {
		fread(buffer+i, 1, 1, archive);
		if (buffer[i] == 0xFD && buffer[i-1] == 0xFD)
			break;
		i++;
	}

	// Try to determine the dc family based on the header type
	switch (buffer[2]) {
		case 0x20:
		case 0x21:
			dc_fam = DC_FAMILY_HW_OSTC;
			break;
		case 0x22:
			dc_fam = DC_FAMILY_HW_FROG;
			break;
		case 0x23:
			dc_fam = DC_FAMILY_HW_OSTC3;
			break;
	}

	// Prepare data to pass to libdivecomputer. OSTC protocol doesn't include
	// a model number so will use 0.
	ostc_prepare_data(model, dc_fam, devdata);
	tmp = calloc(strlen(devdata->vendor)+strlen(devdata->model)+28,1);
	sprintf(tmp,"%s %s (Imported from OSTCTools)", devdata->vendor, devdata->model);
	ostcdive->dc.model =  copy_string(tmp);
	free(tmp);

	// Parse the dive data
	rc = libdc_buffer_parser(ostcdive, devdata, buffer, i+1);
	if (rc != DC_STATUS_SUCCESS)
		report_error("Libdc returned error -%s- for dive %d", errmsg(rc), ostcdive->number);

	// Serial number is not part of the header nor the profile, so libdc won't
	// catch it. If Serial is part of the extra_data, and set to zero, remove
	// it from the list and add again.
	tmp = calloc(12,1);
	sprintf(tmp, "%d", serial);
	ostcdive->dc.serial = copy_string(tmp);
	free(tmp);

	ptr = ostcdive->dc.extra_data;
	while (strcmp(ptr->key, "Serial"))
		ptr = ptr->next;
	if (!strcmp(ptr->value, "0")) {
		add_extra_data(&ostcdive->dc, "Serial", ostcdive->dc.serial);
		*ptr = *(ptr)->next;
	}

	free(devdata);
	free(buffer);
	record_dive_to_table(ostcdive, divetable);
	mark_divelist_changed(true);
	sort_table(divetable);
	fclose(archive);
}
コード例 #9
0
QString ConfigureDiveComputer::dc_open(device_data_t *data)
{
	FILE *fp = NULL;
	dc_status_t rc;

	if (data->libdc_log)
		fp = subsurface_fopen(logfile_name, "w");

	data->libdc_logfile = fp;

	rc = dc_context_new(&data->context);
	if (rc != DC_STATUS_SUCCESS) {
		return tr("Unable to create libdivecomputer context");
	}

	if (fp) {
		dc_context_set_loglevel(data->context, DC_LOGLEVEL_ALL);
		dc_context_set_logfunc(data->context, logfunc, fp);
	}

#if defined(SSRF_CUSTOM_SERIAL)
	if (data->bluetooth_mode) {
#if defined(BT_SUPPORT) && defined(SSRF_CUSTOM_SERIAL)
		rc = dc_context_set_custom_serial(data->context, get_qt_serial_ops());
#endif
#ifdef SERIAL_FTDI
	} else if (!strcmp(data->devname, "ftdi")) {
		rc = dc_context_set_custom_serial(data->context, &serial_ftdi_ops);
#endif
	}

	if (rc != DC_STATUS_SUCCESS) {
		report_error(errmsg(rc));
	} else {
#else
	{
#endif
		rc = dc_device_open(&data->device, data->context, data->descriptor, data->devname);
	}

	if (rc != DC_STATUS_SUCCESS) {
		return tr("Could not a establish connection to the dive computer.");
	}

	setState(OPEN);

	return NULL;
}

void ConfigureDiveComputer::dc_close(device_data_t *data)
{
	if (data->device)
		dc_device_close(data->device);
	data->device = NULL;
	if (data->context)
		dc_context_free(data->context);
	data->context = NULL;

	if (data->libdc_logfile)
		fclose(data->libdc_logfile);

	setState(INITIAL);
}