This will parse date information from Seabear log file and skips the
"header" data to allow parsing of the CSV content.

Signed-off-by: Miika Turkia <miika.tur...@gmail.com>
---
 dive.h                        |   1 +
 file.c                        | 154 ++++++++++++++++++++++++++++++++++--------
 qt-ui/divelogimportdialog.cpp |  46 ++++++-------
 3 files changed, 149 insertions(+), 52 deletions(-)

diff --git a/dive.h b/dive.h
index ef5ff0f..1c30a72 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 6ada903..7ffe8a6 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 51112c4..91c1d73 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);
 
-- 
1.9.1

_______________________________________________
subsurface mailing list
subsurface@subsurface-divelog.org
http://lists.subsurface-divelog.org/cgi-bin/mailman/listinfo/subsurface

Reply via email to