summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dive.h1
-rw-r--r--file.c154
-rw-r--r--qt-ui/divelogimportdialog.cpp46
3 files changed, 149 insertions, 52 deletions
diff --git a/dive.h b/dive.h
index ef5ff0f83..1c30a727c 100644
--- a/dive.h
+++ b/dive.h
@@ -603,6 +603,7 @@ extern int parse_shearwater_buffer(sqlite3 *handle, const char *url, const char
extern int parse_file(const char *filename);
extern int parse_csv_file(const char *filename, int time, int depth, int temp, int po2f, int cnsf, int ndlf, int ttsf, int stopdepthf, int pressuref, int sepidx, const char *csvtemplate, int units);
+extern int parse_seabear_csv_file(const char *filename, int time, int depth, int temp, int po2f, int cnsf, int ndlf, int ttsf, int stopdepthf, int pressuref, int sepidx, const char *csvtemplate, int units);
extern int parse_txt_file(const char *filename, const char *csv);
extern int parse_manual_file(const char *filename, int separator_index, int units, int number, int date, int time, int duration, int location, int gps, int maxdepth, int meandepth, int buddy, int notes, int weight, int tags);
diff --git a/file.c b/file.c
index 6ada903fd..7ffe8a6c1 100644
--- a/file.c
+++ b/file.c
@@ -105,7 +105,7 @@ static int try_to_xslt_open_csv(const char *filename, struct memblock *mem, cons
{
char *buf;
- if (readfile(filename, mem) < 0)
+ if (mem->size == 0 && readfile(filename, mem) < 0)
return report_error(translate("gettextFromC", "Failed to read '%s'"), filename);
/* Surround the CSV file content with XML tags to enable XSLT
@@ -589,29 +589,11 @@ int parse_txt_file(const char *filename, const char *csv)
#define MAXCOLDIGITS 3
#define MAXCOLS 100
-int parse_csv_file(const char *filename, int timef, int depthf, int tempf, int po2f, int cnsf, int ndlf, int ttsf, int stopdepthf, int pressuref, int sepidx, const char *csvtemplate, int unitidx)
+#define DATESTR 9
+#define TIMESTR 6
+void init_csv_file_parsing(char **params, char *timebuf, char *depthbuf, char *tempbuf, char *po2buf, char *cnsbuf, char *ndlbuf, char *ttsbuf, char *stopdepthbuf, char *pressurebuf, char *unitbuf, char *separator_index, time_t *now, struct tm *timep, char *curdate, char *curtime, int timef, int depthf, int tempf, int po2f, int cnsf, int ndlf, int ttsf, int stopdepthf, int pressuref, int sepidx, const char *csvtemplate, int unitidx)
{
- struct memblock mem;
int pnr = 0;
- char *params[27];
- char timebuf[MAXCOLDIGITS];
- char depthbuf[MAXCOLDIGITS];
- char tempbuf[MAXCOLDIGITS];
- char po2buf[MAXCOLDIGITS];
- char cnsbuf[MAXCOLDIGITS];
- char ndlbuf[MAXCOLDIGITS];
- char ttsbuf[MAXCOLDIGITS];
- char stopdepthbuf[MAXCOLDIGITS];
- char pressurebuf[MAXCOLDIGITS];
- char unitbuf[MAXCOLDIGITS];
- char separator_index[MAXCOLDIGITS];
- time_t now;
- struct tm *timep;
- char curdate[9];
- char curtime[6];
-
- if (timef >= MAXCOLS || depthf >= MAXCOLS || tempf >= MAXCOLS || po2f >= MAXCOLS || cnsf >= MAXCOLS || ndlf >= MAXCOLS || cnsf >= MAXCOLS || stopdepthf >= MAXCOLS || pressuref >= MAXCOLS)
- return report_error(translate("gettextFromC", "Maximum number of supported columns on CSV import is %d"), MAXCOLS);
snprintf(timebuf, MAXCOLDIGITS, "%d", timef);
snprintf(depthbuf, MAXCOLDIGITS, "%d", depthf);
@@ -624,13 +606,13 @@ int parse_csv_file(const char *filename, int timef, int depthf, int tempf, int p
snprintf(pressurebuf, MAXCOLDIGITS, "%d", pressuref);
snprintf(separator_index, MAXCOLDIGITS, "%d", sepidx);
snprintf(unitbuf, MAXCOLDIGITS, "%d", unitidx);
- time(&now);
- timep = localtime(&now);
- strftime(curdate, sizeof(curdate), "%Y%m%d", timep);
+ time(now);
+ timep = localtime(now);
+ strftime(curdate, DATESTR, "%Y%m%d", timep);
/* As the parameter is numeric, we need to ensure that the leading zero
* is not discarded during the transform, thus prepend time with 1 */
- strftime(curtime, sizeof(curtime), "1%H%M", timep);
+ strftime(curtime, TIMESTR, "1%H%M", timep);
params[pnr++] = "timeField";
params[pnr++] = timebuf;
@@ -659,10 +641,125 @@ int parse_csv_file(const char *filename, int timef, int depthf, int tempf, int p
params[pnr++] = "separatorIndex";
params[pnr++] = separator_index;
params[pnr++] = NULL;
+}
+
+int parse_csv_file(const char *filename, int timef, int depthf, int tempf, int po2f, int cnsf, int ndlf, int ttsf, int stopdepthf, int pressuref, int sepidx, const char *csvtemplate, int unitidx)
+{
+ struct memblock mem;
+ char *params[27];
+ char timebuf[MAXCOLDIGITS];
+ char depthbuf[MAXCOLDIGITS];
+ char tempbuf[MAXCOLDIGITS];
+ char po2buf[MAXCOLDIGITS];
+ char cnsbuf[MAXCOLDIGITS];
+ char ndlbuf[MAXCOLDIGITS];
+ char ttsbuf[MAXCOLDIGITS];
+ char stopdepthbuf[MAXCOLDIGITS];
+ char pressurebuf[MAXCOLDIGITS];
+ char unitbuf[MAXCOLDIGITS];
+ char separator_index[MAXCOLDIGITS];
+ time_t now;
+ struct tm *timep;
+ char curdate[DATESTR];
+ char curtime[TIMESTR];
+
+ if (timef >= MAXCOLS || depthf >= MAXCOLS || tempf >= MAXCOLS || po2f >= MAXCOLS || cnsf >= MAXCOLS || ndlf >= MAXCOLS || cnsf >= MAXCOLS || stopdepthf >= MAXCOLS || pressuref >= MAXCOLS)
+ return report_error(translate("gettextFromC", "Maximum number of supported columns on CSV import is %d"), MAXCOLS);
+
+ init_csv_file_parsing(params, timebuf, depthbuf, tempbuf, po2buf, cnsbuf,ndlbuf, ttsbuf, stopdepthbuf, pressurebuf, unitbuf, separator_index, &now, timep, curdate, curtime, timef, depthf, tempf, po2f, cnsf, ndlf, ttsf, stopdepthf, pressuref, sepidx, csvtemplate, unitidx);
+
+ if (filename == NULL)
+ return report_error("No CSV filename");
+
+ mem.size = 0;
+ if (try_to_xslt_open_csv(filename, &mem, csvtemplate))
+ return -1;
+
+ parse_xml_buffer(filename, mem.buffer, mem.size, &dive_table, (const char **)params);
+ free(mem.buffer);
+ return 0;
+}
+
+int parse_seabear_csv_file(const char *filename, int timef, int depthf, int tempf, int po2f, int cnsf, int ndlf, int ttsf, int stopdepthf, int pressuref, int sepidx, const char *csvtemplate, int unitidx)
+{
+ struct memblock mem, mem_data;
+ char *params[27];
+ char timebuf[MAXCOLDIGITS];
+ char depthbuf[MAXCOLDIGITS];
+ char tempbuf[MAXCOLDIGITS];
+ char po2buf[MAXCOLDIGITS];
+ char cnsbuf[MAXCOLDIGITS];
+ char ndlbuf[MAXCOLDIGITS];
+ char ttsbuf[MAXCOLDIGITS];
+ char stopdepthbuf[MAXCOLDIGITS];
+ char pressurebuf[MAXCOLDIGITS];
+ char unitbuf[MAXCOLDIGITS];
+ char separator_index[MAXCOLDIGITS];
+ time_t now;
+ struct tm *timep;
+ char curdate[DATESTR];
+ char curtime[TIMESTR];
+ char *ptr, *ptr_old = NULL;
+ char *NL;
+
+ if (timef >= MAXCOLS || depthf >= MAXCOLS || tempf >= MAXCOLS || po2f >= MAXCOLS || cnsf >= MAXCOLS || ndlf >= MAXCOLS || cnsf >= MAXCOLS || stopdepthf >= MAXCOLS || pressuref >= MAXCOLS)
+ return report_error(translate("gettextFromC", "Maximum number of supported columns on CSV import is %d"), MAXCOLS);
+
+ init_csv_file_parsing(params, timebuf, depthbuf, tempbuf, po2buf, cnsbuf,ndlbuf, ttsbuf, stopdepthbuf, pressurebuf, unitbuf, separator_index, &now, timep, curdate, curtime, timef, depthf, tempf, po2f, cnsf, ndlf, ttsf, stopdepthf, pressuref, sepidx, csvtemplate, unitidx);
if (filename == NULL)
return report_error("No CSV filename");
+ if (readfile(filename, &mem) < 0)
+ return report_error(translate("gettextFromC", "Failed to read '%s'"), filename);
+
+ /* Determine NL (new line) character and the start of CSV data */
+ ptr = mem.buffer;
+ while (ptr = strstr(ptr, "\r\n\r\n")) {
+ ptr_old = ptr;
+ ptr += 1;
+ NL = "\r\n";
+ }
+
+ if (!ptr_old) {
+ while (ptr = strstr(ptr, "\n\n")) {
+ ptr_old = ptr;
+ ptr += 1;
+ }
+ ptr_old += 2;
+ NL = "\n";
+ } else
+ ptr_old += 4;
+
+ /*
+ * On my current sample of Seabear DC log file, the date is
+ * without any identifier. Thus we must search for the previous
+ * line and step through from there.
+ */
+ ptr = strstr(mem.buffer, "Serial number:");
+ if (ptr)
+ ptr = strstr(ptr, NL);
+
+ /* Write date and time values to params array */
+ if (ptr) {
+ ptr += strlen(NL) + 2;
+ memcpy(params[19], ptr, 4);
+ memcpy(params[19] + 4, ptr + 5, 2);
+ memcpy(params[19] + 6, ptr + 8, 2);
+ params[19][8] = 0;
+
+ params[21][0] = '1';
+ memcpy(params[21] + 1, ptr + 11, 2);
+ memcpy(params[21] + 3, ptr + 14, 2);
+ params[21][5] = 0;
+ }
+
+ /* Move the CSV data to the start of mem buffer */
+ mem_data.size = (int)mem.size - (ptr_old - (char*)mem.buffer);
+ mem_data.buffer = ptr_old;
+ memmove(mem.buffer, ptr_old, mem.size - (ptr_old - (char*)mem.buffer));
+ mem.size = (int)mem.size - (ptr_old - (char*)mem.buffer);
+
if (try_to_xslt_open_csv(filename, &mem, csvtemplate))
return -1;
@@ -714,11 +811,11 @@ int parse_manual_file(const char *filename, int sepidx, int units, int numberf,
snprintf(unit, MAXCOLDIGITS, "%d", units);
time(&now);
timep = localtime(&now);
- strftime(curdate, sizeof(curdate), "%Y%m%d", timep);
+ strftime(curdate, DATESTR, "%Y%m%d", timep);
/* As the parameter is numeric, we need to ensure that the leading zero
* is not discarded during the transform, thus prepend time with 1 */
- strftime(curtime, sizeof(curtime), "1%H%M", timep);
+ strftime(curtime, TIMESTR, "1%H%M", timep);
params[pnr++] = "numberField";
params[pnr++] = numberbuf;
@@ -757,6 +854,7 @@ int parse_manual_file(const char *filename, int sepidx, int units, int numberf,
if (filename == NULL)
return report_error("No manual CSV filename");
+ mem.size = 0;
if (try_to_xslt_open_csv(filename, &mem, "manualCSV"))
return -1;
diff --git a/qt-ui/divelogimportdialog.cpp b/qt-ui/divelogimportdialog.cpp
index 51112c405..91c1d738e 100644
--- a/qt-ui/divelogimportdialog.cpp
+++ b/qt-ui/divelogimportdialog.cpp
@@ -69,7 +69,8 @@ void DiveLogImportDialog::on_buttonBox_accepted()
{
if (ui->tabWidget->currentIndex() == 0) {
for (int i = 0; i < fileNames.size(); ++i) {
- parse_csv_file(fileNames[i].toUtf8().data(), ui->CSVTime->value() - 1,
+ if (ui->knownImports->currentText() == QString("Seabear CSV")) {
+ parse_seabear_csv_file(fileNames[i].toUtf8().data(), ui->CSVTime->value() - 1,
ui->CSVDepth->value() - 1, VALUE_IF_CHECKED(CSVTemperature),
VALUE_IF_CHECKED(CSVpo2),
VALUE_IF_CHECKED(CSVcns),
@@ -80,6 +81,26 @@ void DiveLogImportDialog::on_buttonBox_accepted()
ui->CSVSeparator->currentIndex(),
specialCSV.contains(ui->knownImports->currentIndex()) ? CSVApps[ui->knownImports->currentIndex()].name.toUtf8().data() : "csv",
ui->CSVUnits->currentIndex());
+
+ /* Seabear CSV stores NDL and TTS in Minutes, not seconds */
+ struct dive *dive = dive_table.dives[dive_table.nr - 1];
+ for(int s_nr = 0 ; s_nr <= dive->dc.samples ; s_nr++) {
+ struct sample *sample = dive->dc.sample + s_nr;
+ sample->ndl.seconds *= 60;
+ sample->tts.seconds *= 60;
+ }
+ } else
+ parse_csv_file(fileNames[i].toUtf8().data(), ui->CSVTime->value() - 1,
+ ui->CSVDepth->value() - 1, VALUE_IF_CHECKED(CSVTemperature),
+ VALUE_IF_CHECKED(CSVpo2),
+ VALUE_IF_CHECKED(CSVcns),
+ VALUE_IF_CHECKED(CSVndl),
+ VALUE_IF_CHECKED(CSVtts),
+ VALUE_IF_CHECKED(CSVstopdepth),
+ VALUE_IF_CHECKED(CSVpressure),
+ ui->CSVSeparator->currentIndex(),
+ specialCSV.contains(ui->knownImports->currentIndex()) ? CSVApps[ui->knownImports->currentIndex()].name.toUtf8().data() : "csv",
+ ui->CSVUnits->currentIndex());
}
} else {
for (int i = 0; i < fileNames.size(); ++i) {
@@ -95,29 +116,6 @@ void DiveLogImportDialog::on_buttonBox_accepted()
VALUE_IF_CHECKED(Tags));
}
}
- if (ui->knownImports->currentText() == QString("Seabear CSV")) {
- /* Seabear CSV stores NDL and TTS in Minutes, not seconds */
- struct dive *dive = dive_table.dives[dive_table.nr - 1];
- for(int s_nr = 0 ; s_nr <= dive->dc.samples ; s_nr++) {
- struct sample *sample = dive->dc.sample + s_nr;
- sample->ndl.seconds *= 60;
- sample->tts.seconds *= 60;
- }
-
- /* And the two first samples are "settings" from there software */
- memmove(dive->dc.sample, dive->dc.sample + 2, sizeof(dive->dc.sample) * dive->dc.samples - 2);
- dive->dc.samples -= 2;
- memset(dive->dc.sample + dive->dc.samples, 0, sizeof(dive->dc.sample) * 2);
-
- /* And fix dammanged temperature from the initial samples */
- dive->mintemp.mkelvin = 0;
- dive->maxtemp.mkelvin = 0;
- dive->watertemp.mkelvin = 0;
- dive->dc.watertemp.mkelvin = 0;
- dive->cylinder[0].start.mbar = 0;
- dive->cylinder[0].sample_start.mbar = 0;
- fixup_dive(dive);
- }
process_dives(true, false);