Browse Source

revive support for ENCODING in xcsv files.

tags/gpsbabel_1_5_4
tsteven4 4 years ago
parent
commit
9192e1f3d0
3 changed files with 87 additions and 25 deletions
  1. 34
    17
      csv_util.cc
  2. 7
    1
      csv_util.h
  3. 46
    7
      xcsv.cc

+ 34
- 17
csv_util.cc View File

@@ -21,9 +21,9 @@
*/

#include <QtCore/QRegExp>
#include <QtCore/QTextStream>

#include "defs.h"
#include "cet_util.h"
#include "csv_util.h"
#include "garmin_fs.h"
#include "grtcirc.h"
@@ -730,7 +730,9 @@ void xcsv_file_init(void)
xcsv_file.badchars = QString();
xcsv_file.ifield_ct = 0;
xcsv_file.ofield_ct = 0;
xcsv_file.xcsvfp = NULL;
xcsv_file.file = NULL;
xcsv_file.stream = NULL;
xcsv_file.codec = NULL;
xcsv_file.fname = QString();
xcsv_file.description = NULL;
xcsv_file.extension = NULL;
@@ -1406,6 +1408,26 @@ xcsv_parse_val(const char* s, Waypoint* wpt, const field_map_t* fmp,
}
}

// TODO: eliminate this routine which is modeled
// after gbfgetstr for legacy compatibility.
static char*
xcsv_readline(char* buff)
{
if (buff) {
xfree(buff);
}
QString line = xcsv_file.stream->readLine();
if (line.isNull()) {
return NULL;
} else {
// TODO: move csv processing to Qt, eliminating the need to go
// back to 8 bit encoding, which is shaky for encoding like utf8
// that have multibyte characters.
char* newbuff = xstrdup(CSTR(line));
return newbuff;
}
}

/*****************************************************************************/
/* xcsv_data_read() - read input file, parsing lines, fields and handling */
/* any data conversion (the input meat) */
@@ -1413,7 +1435,7 @@ xcsv_parse_val(const char* s, Waypoint* wpt, const field_map_t* fmp,
void
xcsv_data_read(void)
{
char* buff;
char* buff = NULL;
char* s;
Waypoint* wpt_tmp;
int linecount = 0;
@@ -1433,11 +1455,8 @@ xcsv_data_read(void)
csv_route = rte;
}

while ((buff = gbfgetstr(xcsv_file.xcsvfp))) {
if ((linecount == 0) && xcsv_file.xcsvfp->unicode) {
cet_convert_init(CET_CHARSET_UTF8, 1);
}

// TODO: stop the back and forth between QString and char strings,
while ((buff = xcsv_readline(buff))) {
linecount++;
/* Whack trailing space; leading space may matter if our field sep
* is whitespace and we have leading whitespace.
@@ -1643,7 +1662,7 @@ xcsv_waypt_pr(const Waypoint* wpt)
fmp = (field_map_t*) elem;

if ((i != 0) && !(fmp->options & OPTIONS_NODELIM)) {
gbfputs(write_delimiter, xcsv_file.xcsvfp);
*xcsv_file.stream << write_delimiter;
}

if (fmp->options & OPTIONS_ABSOLUTE) {
@@ -2152,7 +2171,7 @@ xcsv_waypt_pr(const Waypoint* wpt)

if (!xcsv_file.field_encloser.isEmpty()) {
/* print the enclosing character(s) */
gbfputs(xcsv_file.record_delimiter, xcsv_file.xcsvfp);
*xcsv_file.stream << xcsv_file.record_delimiter;
}

/* As a special case (pronounced "horrible hack") we allow
@@ -2161,16 +2180,16 @@ xcsv_waypt_pr(const Waypoint* wpt)
if (0 == strcmp(fmp->printfc, "\"%s\"")) {
obuff = '"' + obuff + '"';
}
gbfputs(obuff, xcsv_file.xcsvfp);
*xcsv_file.stream << obuff;

if (!xcsv_file.field_encloser.isEmpty()) {
/* print the enclosing character(s) */
gbfputs(xcsv_file.record_delimiter, xcsv_file.xcsvfp);
*xcsv_file.stream << xcsv_file.record_delimiter;
}
buff.clear();
}

gbfputs(xcsv_file.record_delimiter, xcsv_file.xcsvfp);
*xcsv_file.stream << xcsv_file.record_delimiter;

/* increment the index counter */
waypt_out_count++;
@@ -2227,8 +2246,7 @@ xcsv_data_write(void)
QString t = dt.toString("hh:mm:ss");
cout.replace("__TIME__", t);
}
gbfputs(cout, xcsv_file.xcsvfp);
gbfputs(xcsv_file.record_delimiter, xcsv_file.xcsvfp);
*xcsv_file.stream << cout << xcsv_file.record_delimiter;
}

if ((xcsv_file.datatype == 0) || (xcsv_file.datatype == wptdata)) {
@@ -2243,8 +2261,7 @@ xcsv_data_write(void)

/* output epilogue lines, if any. */
foreach(const QString& ogp, xcsv_file.epilogue) {
gbfputs(ogp, xcsv_file.xcsvfp);
gbfputs(xcsv_file.record_delimiter, xcsv_file.xcsvfp);
*xcsv_file.stream << ogp << xcsv_file.record_delimiter;
}
}
#endif

+ 7
- 1
csv_util.h View File

@@ -96,6 +96,10 @@ typedef struct char_map {
const char* chars;
} char_map_t;

namespace gpsbabel
{
class File;
}
/*
* a Class describing all the wonderful elements of xcsv files, in a
* nutshell.
@@ -125,7 +129,9 @@ class XcsvFile {
int ifield_ct; /* actual # of ifields */
int ofield_ct; /* actual # of ofields */

gbfile* xcsvfp; /* ptr to current *open* data file */
gpsbabel::File* file;
QTextStream* stream;
QTextCodec* codec;
QString fname; /* ptr to filename of above. */

char* description; /* Description for help text */

+ 46
- 7
xcsv.cc View File

@@ -23,10 +23,14 @@

*/

#include <QtCore/QTextCodec>
#include <QtCore/QTextStream>

#include "defs.h"
#include "cet_util.h"
#include "csv_util.h"
#include "jeeps/gpsmath.h"
#include "src/core/file.h"
#include "src/core/logging.h"
#include <ctype.h>
#include <stdlib.h>

@@ -335,7 +339,10 @@ xcsv_parse_style_line(char* sbuff)

if (ISSTOKEN(sbuff, "ENCODING")) {
p = csv_stringtrim(&sbuff[8], "\"", 1);
cet_convert_init(p, 1);
xcsv_file.codec = QTextCodec::codecForName(p);
if (!xcsv_file.codec) {
Fatal() << "Unsupported character set '" << p << "'.";
}
xfree(p);
} else

@@ -554,7 +561,16 @@ xcsv_rd_init(const QString& fname)
}
}

xcsv_file.xcsvfp = gbfopen(fname, "r", MYNAME);
xcsv_file.file = new gpsbabel::File(fname);
xcsv_file.file->open(QFile::ReadOnly);
xcsv_file.stream = new QTextStream(xcsv_file.file);
if (xcsv_file.codec) {
xcsv_file.stream->setCodec(xcsv_file.codec);
} else {
// default to UTF-8.
xcsv_file.stream->setCodec("UTF-8");
xcsv_file.stream->setAutoDetectUnicode(true);
}
xcsv_file.gps_datum = GPS_Lookup_Datum_Index(opt_datum);
is_fatal(xcsv_file.gps_datum < 0, MYNAME ": datum \"%s\" is not supported.", opt_datum);
}
@@ -562,7 +578,12 @@ xcsv_rd_init(const QString& fname)
static void
xcsv_rd_deinit(void)
{
gbfclose(xcsv_file.xcsvfp);
xcsv_file.file->close();
delete xcsv_file.file;
xcsv_file.file = NULL;
delete xcsv_file.stream;
xcsv_file.stream = NULL;
xcsv_file.codec = NULL;

xcsv_destroy_style();
}
@@ -586,7 +607,19 @@ xcsv_wr_init(const QString& fname)
xcsv_read_style(styleopt);
}

xcsv_file.xcsvfp = gbfopen(fname, "w", MYNAME);
xcsv_file.file = new gpsbabel::File(fname);
xcsv_file.file->open(QFile::WriteOnly | QFile::Text);
xcsv_file.stream = new QTextStream(xcsv_file.file);
if (xcsv_file.codec) {
xcsv_file.stream->setCodec(xcsv_file.codec);
// enable bom for all UTF codecs except UTF-8
if (xcsv_file.codec->mibEnum() != 106) {
xcsv_file.stream->setGenerateByteOrderMark(true);
}
} else {
// emulate gbfputs which assumes UTF-8.
xcsv_file.stream->setCodec("UTF-8");
}
xcsv_file.fname = fname;

/* set mkshort options from the command line */
@@ -624,7 +657,13 @@ xcsv_wr_position_init(const QString& fname)
static void
xcsv_wr_deinit(void)
{
gbfclose(xcsv_file.xcsvfp);
xcsv_file.stream->flush();
xcsv_file.file->close();
delete xcsv_file.file;
xcsv_file.file = NULL;
delete xcsv_file.stream;
xcsv_file.stream = NULL;
xcsv_file.codec = NULL;

xcsv_destroy_style();
}
@@ -652,7 +691,7 @@ xcsv_wr_position(Waypoint* wpt)
xcsv_data_write();
waypt_del(wpt);

gbfflush(xcsv_file.xcsvfp);
xcsv_file.stream->flush();
}

ff_vecs_t xcsv_vecs = {

Loading…
Cancel
Save