kopia lustrzana https://github.com/jamescoxon/dl-fldigi
Modification to logbook file processing
* Performance enhancement to file reading and processing * original, 33 seconds to process 22200 records * new, 0.55 seconds to process 22200 recordspull/2/head
rodzic
4dfb2c596c
commit
0bb3f8fe2e
|
@ -7,10 +7,12 @@
|
|||
struct FIELD {
|
||||
int type;
|
||||
const char *name;
|
||||
int len;
|
||||
int size;
|
||||
Fl_Check_Button **btn;
|
||||
};
|
||||
|
||||
extern FIELD fields[];
|
||||
extern int numfields;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -16,7 +16,7 @@ private:
|
|||
FILE *adiFile;
|
||||
void fillfield(int, char *);
|
||||
public:
|
||||
cAdifIO () {};
|
||||
cAdifIO ();
|
||||
~cAdifIO () {};
|
||||
int readAdifRec () {return 0;};
|
||||
int writeAdifRec () {return 0;};
|
||||
|
|
|
@ -14,42 +14,40 @@ enum ADIF_FIELD_POS {
|
|||
COUNTRY,
|
||||
CQZ,
|
||||
DXCC,
|
||||
EXPORT, // flag used internally in fldigi's logbook
|
||||
FREQ,
|
||||
GRIDSQUARE,
|
||||
IOTA,
|
||||
ITUZ,
|
||||
MODE,
|
||||
MYXCHG, // contest exchange field #3
|
||||
NAME,
|
||||
NOTES,
|
||||
OPERATOR,
|
||||
PFX,
|
||||
PROP_MODE,
|
||||
QSLRDATE,
|
||||
QSLSDATE,
|
||||
QSL_MSG,
|
||||
QSL_RCVD,
|
||||
QSL_SENT,
|
||||
QSL_VIA,
|
||||
QSO_DATE,
|
||||
QTH,
|
||||
RST_RCVD,
|
||||
RST_SENT,
|
||||
STATE,
|
||||
STX,
|
||||
TIME_OFF,
|
||||
TIME_ON,
|
||||
TX_PWR,
|
||||
// additional for 2.0
|
||||
IOTA,
|
||||
ITUZ,
|
||||
OPERATOR,
|
||||
PFX,
|
||||
PROP_MODE,
|
||||
QSL_MSG,
|
||||
QSL_VIA,
|
||||
RX_PWR,
|
||||
SAT_MODE,
|
||||
SAT_NAME,
|
||||
SRX,
|
||||
STATE,
|
||||
STX,
|
||||
TEN_TEN,
|
||||
TIME_OFF,
|
||||
TIME_ON,
|
||||
TX_PWR,
|
||||
VE_PROV,
|
||||
// following fields are specific to fldigi's logbook
|
||||
XCHG1, // contest exchange field
|
||||
MYXCHG, // contest exchange field #3
|
||||
EXPORT, // flag used internally in fldigi's logbook
|
||||
NUMFIELDS // counter for number of fields in enum
|
||||
};
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ public:
|
|||
cQsoRec ();
|
||||
~cQsoRec ();
|
||||
void putField (int, const char *);
|
||||
void putField (int, const char *, int);
|
||||
void addtoField (int, const char *);
|
||||
char *getField (int);
|
||||
void trimFields();
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <ctime>
|
||||
|
||||
#include "adif_io.h"
|
||||
#include "config.h"
|
||||
|
@ -21,106 +22,129 @@ static const char *szEOL = "\n";
|
|||
|
||||
FIELD fields[] = {
|
||||
// TYPE, NAME, SIZE
|
||||
{ADDRESS, "ADDRESS", 40, NULL}, // contacted stations mailing address
|
||||
{AGE, "AGE", 3, NULL}, // contacted operators age in years
|
||||
{ARRL_SECT, "ARRL_SECT", 12, NULL}, // contacted stations ARRL section
|
||||
{BAND, "BAND", 6, &btnSelectBand}, // QSO band
|
||||
{CALL, "CALL", 10, &btnSelectCall}, // contacted stations CALLSIGN
|
||||
{CNTY, "CNTY", 20, NULL}, // secondary political subdivision, ie: county
|
||||
{COMMENT, "COMMENT", 80, NULL}, // comment field for QSO
|
||||
{CONT, "CONT", 10, NULL}, // contacted stations continent
|
||||
{CONTEST_ID, "CONTEST_ID", 6, NULL}, // QSO contest identifier
|
||||
{COUNTRY, "COUNTRY", 20, &btnSelectCountry}, // contacted stations DXCC entity name
|
||||
{CQZ, "CQZ", 8, NULL}, // contacted stations CQ Zone
|
||||
{DXCC, "DXCC", 8, &btnSelectDXCC}, // contacted stations Country Code
|
||||
{FREQ, "FREQ", 10, &btnSelectFreq}, // QSO frequency in Mhz
|
||||
{GRIDSQUARE, "GRIDSQUARE", 6, &btnSelectLOC}, // contacted stations Maidenhead Grid Square
|
||||
{MODE, "MODE", 8, &btnSelectMode}, // QSO mode
|
||||
{NAME, "NAME", 18, &btnSelectName}, // contacted operators NAME
|
||||
{NOTES, "NOTES", 80, &btnSelectNotes}, // QSO notes
|
||||
{QSLRDATE, "QSLRDATE", 8, &btnSelectQSLrcvd}, // QSL received date
|
||||
{QSLSDATE, "QSLSDATE", 8, &btnSelectQSLsent}, // QSL sent date
|
||||
{QSL_RCVD, "QSL_RCVD", 1, NULL}, // QSL received status
|
||||
{QSL_SENT, "QSL_SENT", 1, NULL}, // QSL sent status
|
||||
{QSO_DATE, "QSO_DATE", 8, &btnSelectQSOdate}, // QSO data
|
||||
{QTH, "QTH", 30, &btnSelectQth}, // contacted stations city
|
||||
{RST_RCVD, "RST_RCVD", 3, &btnSelectRSTrcvd}, // received signal report
|
||||
{RST_SENT, "RST_SENT", 3, &btnSelectRSTsent}, // sent signal report
|
||||
{STATE, "STATE", 2, &btnSelectState}, // contacted stations STATE
|
||||
{STX, "STX", 8, &btnSelectSerialOUT}, // QSO transmitted serial number
|
||||
{TIME_OFF, "TIME_OFF", 4, &btnSelectTimeOFF}, // HHMM or HHMMSS in UTC
|
||||
{TIME_ON, "TIME_ON", 4, &btnSelectTimeON}, // HHMM or HHMMSS in UTC
|
||||
{TX_PWR, "TX_PWR", 4, &btnSelectTX_pwr}, // power transmitted by this station
|
||||
// new fields
|
||||
{IOTA, "IOTA", 6, &btnSelectIOTA}, // Islands on the air
|
||||
{ITUZ, "ITUZ", 6, NULL}, // ITU zone
|
||||
{OPERATOR, "OPERATOR", 10, NULL}, // Callsign of person loggin the QSO
|
||||
{PFX, "PFX", 5, NULL}, // WPA prefix
|
||||
{PROP_MODE, "PROP_MODE", 5, NULL}, // propogation mode
|
||||
{QSL_MSG, "QSL_MSG", 80, NULL}, // personal message to appear on qsl card
|
||||
{QSL_VIA, "QSL_VIA", 30, NULL},
|
||||
{RX_PWR, "RX_PWR", 4, NULL}, // power of other station in watts
|
||||
{SAT_MODE, "SAT_MODE", 8, NULL}, // satellite mode
|
||||
{SAT_NAME, "SAT_NAME", 12, NULL}, // satellite name
|
||||
{SRX, "SRX", 5, &btnSelectSerialIN}, // received serial number for a contest QSO
|
||||
{TEN_TEN, "TEN_TEN", 10, NULL}, // ten ten # of other station
|
||||
{VE_PROV, "VE_PROV", 2, &btnSelectProvince}, // 2 letter abbreviation for Canadian Province
|
||||
// fldigi specific fields
|
||||
{XCHG1, "XCHG1", 20, &btnSelectXchgIn}, // contest exchange #1 / free1 in xlog
|
||||
{MYXCHG, "MYXCHG", 20, &btnSelectMyXchg}, // contest exchange sent
|
||||
{EXPORT, "EXPORT", 1, NULL} // used to indicate record is to be exported
|
||||
{ADDRESS, "ADDRESS", 0, 40, NULL}, // contacted stations mailing address
|
||||
{AGE, "AGE", 0, 3, NULL}, // contacted operators age in years
|
||||
{ARRL_SECT, "ARRL_SECT", 0, 12, NULL}, // contacted stations ARRL section
|
||||
{BAND, "BAND", 0, 6, &btnSelectBand}, // QSO band
|
||||
{CALL, "CALL", 0, 10, &btnSelectCall}, // contacted stations CALLSIGN
|
||||
{CNTY, "CNTY", 0, 20, NULL}, // secondary political subdivision, ie: county
|
||||
{COMMENT, "COMMENT", 0, 80, NULL}, // comment field for QSO
|
||||
{CONT, "CONT", 0, 10, NULL}, // contacted stations continent
|
||||
{CONTEST_ID, "CONTEST_ID", 0, 6, NULL}, // QSO contest identifier
|
||||
{COUNTRY, "COUNTRY", 0, 20, &btnSelectCountry}, // contacted stations DXCC entity name
|
||||
{CQZ, "CQZ", 0, 8, NULL}, // contacted stations CQ Zone
|
||||
{DXCC, "DXCC", 0, 8, &btnSelectDXCC}, // contacted stations Country Code
|
||||
{EXPORT, "EXPORT", 0, 1, NULL}, // used to indicate record is to be exported
|
||||
{FREQ, "FREQ", 0, 10, &btnSelectFreq}, // QSO frequency in Mhz
|
||||
{GRIDSQUARE, "GRIDSQUARE", 0, 6, &btnSelectLOC}, // contacted stations Maidenhead Grid Square
|
||||
{IOTA, "IOTA", 0, 6, &btnSelectIOTA}, // Islands on the air
|
||||
{ITUZ, "ITUZ", 0, 6, NULL}, // ITU zone
|
||||
{MODE, "MODE", 0, 8, &btnSelectMode}, // QSO mode
|
||||
{MYXCHG, "MYXCHG", 0, 20, &btnSelectMyXchg}, // contest exchange sent
|
||||
{NAME, "NAME", 0, 18, &btnSelectName}, // contacted operators NAME
|
||||
{NOTES, "NOTES", 0, 80, &btnSelectNotes}, // QSO notes
|
||||
{OPERATOR, "OPERATOR", 0, 10, NULL}, // Callsign of person loggin the QSO
|
||||
{PFX, "PFX", 0, 5, NULL}, // WPA prefix
|
||||
{PROP_MODE, "PROP_MODE", 0, 5, NULL}, // propogation mode
|
||||
{QSLRDATE, "QSLRDATE", 0, 8, &btnSelectQSLrcvd}, // QSL received date
|
||||
{QSLSDATE, "QSLSDATE", 0, 8, &btnSelectQSLsent}, // QSL sent date
|
||||
{QSL_MSG, "QSL_MSG", 0, 80, NULL}, // personal message to appear on qsl card
|
||||
{QSL_RCVD, "QSL_RCVD", 0, 1, NULL}, // QSL received status
|
||||
{QSL_SENT, "QSL_SENT", 0, 1, NULL}, // QSL sent status
|
||||
{QSL_VIA, "QSL_VIA", 0, 30, NULL},
|
||||
{QSO_DATE, "QSO_DATE", 0, 8, &btnSelectQSOdate}, // QSO data
|
||||
{QTH, "QTH", 0, 30, &btnSelectQth}, // contacted stations city
|
||||
{RST_RCVD, "RST_RCVD", 0, 3, &btnSelectRSTrcvd}, // received signal report
|
||||
{RST_SENT, "RST_SENT", 0, 3, &btnSelectRSTsent}, // sent signal report
|
||||
{RX_PWR, "RX_PWR", 0, 4, NULL}, // power of other station in watts
|
||||
{SAT_MODE, "SAT_MODE", 0, 8, NULL}, // satellite mode
|
||||
{SAT_NAME, "SAT_NAME", 0, 12, NULL}, // satellite name
|
||||
{SRX, "SRX", 0, 5, &btnSelectSerialIN}, // received serial number for a contest QSO
|
||||
{STATE, "STATE", 0, 2, &btnSelectState}, // contacted stations STATE
|
||||
{STX, "STX", 0, 8, &btnSelectSerialOUT}, // QSO transmitted serial number
|
||||
{TEN_TEN, "TEN_TEN", 0, 10, NULL}, // ten ten # of other station
|
||||
{TIME_OFF, "TIME_OFF", 0, 4, &btnSelectTimeOFF}, // HHMM or HHMMSS in UTC
|
||||
{TIME_ON, "TIME_ON", 0, 4, &btnSelectTimeON}, // HHMM or HHMMSS in UTC
|
||||
{TX_PWR, "TX_PWR", 0, 4, &btnSelectTX_pwr}, // power transmitted by this station
|
||||
{VE_PROV, "VE_PROV", 0, 2, &btnSelectProvince}, // 2 letter abbreviation for Canadian Province
|
||||
{XCHG1, "XCHG1", 0, 20, &btnSelectXchgIn} // contest exchange #1 / free1 in xlog
|
||||
};
|
||||
|
||||
int numfields = sizeof(fields) / sizeof(FIELD);
|
||||
|
||||
void initfields()
|
||||
{
|
||||
for (int i = 0; i < numfields; i++)
|
||||
fields[i].len = strlen(fields[i].name);
|
||||
}
|
||||
|
||||
int fieldnbr (const char *s) {
|
||||
for (int i = 0; i < EXPORT; i++)
|
||||
for (int i = 0; i < numfields; i++)
|
||||
if (strncasecmp( fields[i].name, s, fields[i].size) == 0) {
|
||||
if (i == COMMENT) i = NOTES;
|
||||
return i;
|
||||
if (fields[i].type == COMMENT) return(NOTES);
|
||||
return fields[i].type;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int findfield (char *p) {
|
||||
for (int i=0; i < EXPORT; i++)
|
||||
if (strncasecmp (p, fields[i].name, strlen(fields[i].name)) == 0) {
|
||||
if (i == COMMENT) i = NOTES;
|
||||
return i;
|
||||
}
|
||||
int findfield( char *p )
|
||||
{
|
||||
int low = 0;
|
||||
int high = numfields - 1;
|
||||
int middle;
|
||||
int test;
|
||||
|
||||
if (strncasecmp (p, "EOR>", 4) == 0)
|
||||
return -1;
|
||||
return -2;
|
||||
|
||||
while( low <= high ) {
|
||||
middle = ( low + high ) / 2;
|
||||
if ( (test = strncasecmp( p,
|
||||
fields[middle].name,
|
||||
fields[middle].len ) ) == 0 ) { //match
|
||||
if (fields[middle].type == COMMENT) return(NOTES);
|
||||
return fields[middle].type;
|
||||
}
|
||||
else if( test < 0 )
|
||||
high = middle - 1; //search low end of array
|
||||
else
|
||||
low = middle + 1; //search high end of array
|
||||
}
|
||||
return -2; //search key not found
|
||||
}
|
||||
|
||||
cAdifIO::cAdifIO ()
|
||||
{
|
||||
initfields();
|
||||
}
|
||||
|
||||
void cAdifIO::fillfield (int fieldnum, char *buff){
|
||||
char *p = buff;
|
||||
char numeral[8];
|
||||
const char *p = buff;
|
||||
int n, fldsize;
|
||||
memset (numeral, 0, 8);
|
||||
n = 0;
|
||||
while (*p != ':' && n < 11) {p++; n++;}
|
||||
if (n == 11) return; // bad ADIF specifier ---> no ':' after field name
|
||||
// found first ':'
|
||||
p++;
|
||||
n = 0;
|
||||
while (*p >= '0' && *p <= '9' && n < 8) {
|
||||
numeral[n++] = *p;
|
||||
fldsize = 0;
|
||||
const char *p2 = strchr(buff,'>');
|
||||
if (!p2) return;
|
||||
while (p != p2) {
|
||||
if (*p >= '0' && *p <= '9' && n < 8) {
|
||||
fldsize = fldsize * 10 + *p - '0';
|
||||
n++;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
fldsize = atoi(numeral);
|
||||
p = strchr(buff,'>'); // end of specifier +1 == > start of data
|
||||
if (!p) return;
|
||||
p++;
|
||||
char *flddata = new char[fldsize+1];
|
||||
memset (flddata, 0, fldsize + 1);
|
||||
strncpy (flddata, p, fldsize);
|
||||
adifqso.putField (fieldnum, (const char *)flddata);
|
||||
delete [] flddata;
|
||||
adifqso.putField (fieldnum, p2+1, fldsize);
|
||||
}
|
||||
|
||||
void cAdifIO::readFile (const char *fname, cQsoDb *db) {
|
||||
long filesize = 0;
|
||||
char *buff;
|
||||
int found;
|
||||
|
||||
// open the adif file
|
||||
adiFile = fopen (fname, "r");
|
||||
if (!adiFile)
|
||||
|
@ -162,6 +186,7 @@ void cAdifIO::readFile (const char *fname, cQsoDb *db) {
|
|||
|
||||
p2 = strchr(p1,'<'); // find first ADIF specifier
|
||||
adifqso.clearRec();
|
||||
|
||||
while (p2) {
|
||||
found = findfield(p2+1); // -2 ==> not found; -1 <eor> 0 ...N field #
|
||||
// if (found == -2 ) return; // unknown field
|
||||
|
|
|
@ -18,7 +18,7 @@ bool cQsoDb::reverse = false;
|
|||
cQsoRec::cQsoRec() {
|
||||
for (int i=0;i < NUMFIELDS; i++) {
|
||||
qsofield[i] = new char [fields[i].size + 1];
|
||||
memset (qsofield[i],0, fields[i].size + 1);
|
||||
memset (qsofield[i], 0, fields[i].size + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,15 @@ void cQsoRec::checkBand() {
|
|||
|
||||
void cQsoRec::putField (int n, const char *s){
|
||||
if (n < 0 || n >= NUMFIELDS) return;
|
||||
strncpy( qsofield[n], s, fields[n].size);
|
||||
memset(qsofield[n], 0, fields[n].size);
|
||||
strcpy( qsofield[n], s);
|
||||
}
|
||||
|
||||
void cQsoRec::putField (int n, const char *s, int len) {
|
||||
if (n < 0 || n >= NUMFIELDS) return;
|
||||
if (len > fields[n].size) len = fields[n].size;
|
||||
strncpy(qsofield[n], s, len);
|
||||
qsofield[n][len] = 0;
|
||||
}
|
||||
|
||||
void cQsoRec::addtoField (int n, const char *s){
|
||||
|
@ -246,10 +254,12 @@ int i, j, max;
|
|||
//======================================================================
|
||||
// class cQsoDb
|
||||
|
||||
#define MAXRECS 8192
|
||||
|
||||
cQsoDb::cQsoDb() {
|
||||
nbrrecs = 0;
|
||||
maxrecs = 1;
|
||||
qsorec = new cQsoRec[1];
|
||||
maxrecs = MAXRECS;
|
||||
qsorec = new cQsoRec[maxrecs];
|
||||
compby = COMPDATE;
|
||||
dirty = 0;
|
||||
}
|
||||
|
@ -260,9 +270,9 @@ cQsoDb::~cQsoDb() {
|
|||
|
||||
void cQsoDb::deleteRecs() {
|
||||
delete [] qsorec;
|
||||
qsorec = new cQsoRec[1];
|
||||
nbrrecs = 0;
|
||||
maxrecs = 1;
|
||||
maxrecs = MAXRECS;
|
||||
qsorec = new cQsoRec[maxrecs];
|
||||
dirty = 0;
|
||||
}
|
||||
|
||||
|
@ -278,13 +288,11 @@ int cQsoDb::qsoFindRec(cQsoRec *rec) {
|
|||
}
|
||||
|
||||
void cQsoDb::qsoNewRec (cQsoRec *nurec) {
|
||||
nurec->trimFields();
|
||||
if (qsoFindRec(nurec) > -1) return;
|
||||
if (nbrrecs == maxrecs) {
|
||||
maxrecs *= 2;
|
||||
cQsoRec *atemp = new cQsoRec[maxrecs];
|
||||
for (int i = 0; i < nbrrecs; i++)
|
||||
atemp[i] = qsorec[i];
|
||||
atemp[i] = qsorec[i];
|
||||
delete [] qsorec;
|
||||
qsorec = atemp;
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue