summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dive.h3
-rw-r--r--file.c25
-rw-r--r--parse-xml.c104
3 files changed, 129 insertions, 3 deletions
diff --git a/dive.h b/dive.h
index 9f3df313d..e454420eb 100644
--- a/dive.h
+++ b/dive.h
@@ -644,7 +644,8 @@ extern void parse_xml_buffer(const char *url, const char *buf, int size, struct
extern void parse_xml_exit(void);
extern void set_filename(const char *filename, bool force);
-extern int parse_dm4_buffer(const sqlite3 *handle, const char *url, const char *buf, int size, struct dive_table *table, char **error);
+extern int parse_dm4_buffer(sqlite3 *handle, const char *url, const char *buf, int size, struct dive_table *table, char **error);
+extern int parse_shearwater_buffer(sqlite3 *handle, const char *url, const char *buf, int size, struct dive_table *table, char **error);
extern void parse_file(const char *filename, char **error);
extern void parse_csv_file(const char *filename, int time, int depth, int temp, int po2f, int cnsf, int stopdepthf, int sepidx, const char *csvtemplate, char **error);
diff --git a/file.c b/file.c
index b218a13e2..08b61b234 100644
--- a/file.c
+++ b/file.c
@@ -151,9 +151,17 @@ static int try_to_xslt_open_csv(const char *filename, struct memblock *mem, char
return 0;
}
+int db_test_func(void *param, int columns, char **data, char **column)
+{
+ return *data[0] == '0';
+}
+
+
static int try_to_open_db(const char *filename, struct memblock *mem, char **error)
{
sqlite3 *handle;
+ char dm4_test[] = "select count(*) from sqlite_master where type='table' and name='Dive' and sql like '%ProfileBlob%'";
+ char shearwater_test[] = "select count(*) from sqlite_master where type='table' and name='system' and sql like '%dbVersion%'";
int retval;
retval = sqlite3_open(filename, &handle);
@@ -163,7 +171,22 @@ static int try_to_open_db(const char *filename, struct memblock *mem, char **err
return 1;
}
- retval = parse_dm4_buffer(handle, filename, mem->buffer, mem->size, &dive_table, error);
+ /* Testing if DB schema resembles Suunto DM4 database format */
+ retval = sqlite3_exec(handle, dm4_test, &db_test_func, 0, NULL);
+ if (!retval) {
+ retval = parse_dm4_buffer(handle, filename, mem->buffer, mem->size, &dive_table, error);
+ sqlite3_close(handle);
+ return retval;
+ }
+
+ /* Testing if DB schema resembles Shearwater database format */
+ retval = sqlite3_exec(handle, shearwater_test, &db_test_func, 0, NULL);
+ if (!retval) {
+ retval = parse_shearwater_buffer(handle, filename, mem->buffer, mem->size, &dive_table, error);
+ sqlite3_close(handle);
+ return retval;
+ }
+
sqlite3_close(handle);
return retval;
diff --git a/parse-xml.c b/parse-xml.c
index 60a13c336..b93906f55 100644
--- a/parse-xml.c
+++ b/parse-xml.c
@@ -18,6 +18,7 @@
#include "device.h"
int verbose, quit;
+int metric = 1;
static xmlDoc *test_xslt_transforms(xmlDoc *doc, const char **params, char **error);
@@ -1861,7 +1862,7 @@ extern int dm4_dive(void *param, int columns, char **data, char **column)
return SQLITE_OK;
}
-int parse_dm4_buffer(const sqlite3 *handle, const char *url, const char *buffer, int size,
+int parse_dm4_buffer(sqlite3 *handle, const char *url, const char *buffer, int size,
struct dive_table *table, char **error)
{
int retval;
@@ -1882,6 +1883,107 @@ int parse_dm4_buffer(const sqlite3 *handle, const char *url, const char *buffer,
return 0;
}
+extern int shearwater_profile_sample(void *handle, int columns, char **data, char **column)
+{
+ sample_start();
+ if (data[0])
+ cur_sample->time.seconds = atoi(data[0]);
+ if (data[1])
+ cur_sample->depth.mm = metric ? atof(data[1]) * 1000 : feet_to_mm(atof(data[1]));
+ if (data[2])
+ cur_sample->temperature.mkelvin = metric ? C_to_mkelvin(atof(data[2])) : F_to_mkelvin(atof(data[2]));
+
+ /* We don't actually have data[3], but it should appear in the
+ * SQL query at some point.
+ if (data[3])
+ cur_sample->cylinderpressure.mbar = metric ? atoi(data[3]) * 1000 : psi_to_mbar(atoi(data[3]));
+ */
+ sample_end();
+
+ return 0;
+}
+
+extern int shearwater_dive(void *param, int columns, char **data, char **column)
+{
+ int i, interval, retval = 0;
+ sqlite3 *handle = (sqlite3 *)param;
+ float *profileBlob;
+ unsigned char *tempBlob;
+ char *err = NULL;
+ char *location, *site;
+ char get_profile_template[] = "select currentTime,currentDepth,waterTemp from dive_log_records where diveLogId = %d";
+ char get_tags_template[] = "select Text from DiveTag where DiveId = %d";
+ char get_profile_sample[128];
+
+ dive_start();
+ cur_dive->number = atoi(data[0]);
+
+ cur_dive->when = (time_t)(atol(data[1]));
+
+ if (data[2])
+ utf8_string(data[2], &cur_dive->location);
+ if (data[3])
+ utf8_string(data[3], &cur_dive->buddy);
+ if (data[4])
+ utf8_string(data[4], &cur_dive->notes);
+
+ metric = atoi(data[5]) == 1 ? 0 : 1;
+
+ /* TODO: verify that metric calculation is correct */
+ if (data[6])
+ cur_dive->dc.maxdepth.mm = metric ? atof(data[6]) * 1000 : feet_to_mm(atof(data[6]));
+
+ if (data[7])
+ cur_dive->dc.duration.seconds = atoi(data[7]) * 60;
+
+ if (data[8])
+ cur_dive->dc.surface_pressure.mbar = atoi(data[8]);
+ /*
+ * TODO: the deviceid hash should be calculated here.
+ */
+ settings_start();
+ dc_settings_start();
+ if (data[9])
+ utf8_string(data[9], &cur_settings.dc.serial_nr);
+ if (data[10])
+ utf8_string(data[10], &cur_settings.dc.model);
+
+ cur_settings.dc.deviceid = 0xffffffff;
+ dc_settings_end();
+ settings_end();
+
+ snprintf(get_profile_sample, sizeof(get_profile_sample) - 1, get_profile_template, cur_dive->number);
+ retval = sqlite3_exec(handle, get_profile_sample, &shearwater_profile_sample, 0, &err);
+ if (retval != SQLITE_OK) {
+ fprintf(stderr, "%s", translate("gettextFromC","Database query get_profile_sample failed.\n"));
+ return 1;
+ }
+
+ dive_end();
+
+ return SQLITE_OK;
+}
+
+
+int parse_shearwater_buffer(sqlite3 *handle, const char *url, const char *buffer, int size,
+ struct dive_table *table, char **error)
+{
+ int retval;
+ char *err = NULL;
+ target_table = table;
+
+ char get_dives[] = "select i.diveId,timestamp,location||' / '||site,buddy,notes,imperialUnits,maxDepth,maxTime,startSurfacePressure,computerSerial,computerModel FROM dive_info AS i JOIN dive_logs AS l ON i.diveId=l.diveId";
+
+ retval = sqlite3_exec(handle, get_dives, &shearwater_dive, handle, &err);
+
+ if (retval != SQLITE_OK) {
+ fprintf(stderr, translate("gettextFromC","Database query failed '%s'.\n"), url);
+ return 1;
+ }
+
+ return 0;
+}
+
void parse_xml_init(void)
{
LIBXML_TEST_VERSION