mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-02-13 16:18:42 +00:00
230 lines
7.6 KiB
C
230 lines
7.6 KiB
C
/*
|
|
* $Id: ptpk.c,v 1.1 2006/05/27 16:17:25 srhea Exp $
|
|
*
|
|
* Copyright (c) 2006 Sean C. Rhea (srhea@srhea.net)
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the Free
|
|
* Software Foundation; either version 2 of the License, or (at your option)
|
|
* any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc., 51
|
|
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#include <assert.h>
|
|
#include <errno.h>
|
|
#include <math.h>
|
|
#include <regex.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <time.h>
|
|
#include "pt.h"
|
|
|
|
void
|
|
pt_pack(FILE *in, FILE *out, int wheel_sz_mm, int rec_int)
|
|
{
|
|
double mins, nm, mph, watts, miles;
|
|
int cad, hr, interval = 0;
|
|
double last_mins = 0.0, last_miles = 0.0;
|
|
int last_interval = 0;
|
|
int i;
|
|
struct tm start_tm, inc_tm;
|
|
time_t start_time, inc_time;
|
|
int lineno = 1;
|
|
char line[256];
|
|
unsigned char buf[6];
|
|
regex_t date_reg;
|
|
int date_nmatch = 7;
|
|
regmatch_t *date_pmatch =
|
|
(regmatch_t*) calloc(date_nmatch, sizeof(regmatch_t));
|
|
regex_t rider_reg;
|
|
int rider_nmatch = 12;
|
|
regmatch_t *rider_pmatch =
|
|
(regmatch_t*) calloc(rider_nmatch, sizeof(regmatch_t));
|
|
|
|
if (regcomp(&date_reg, "^<RideDate>([0-9][0-9]?)\\\\([0-9][0-9]?)\\\\"
|
|
"([0-9][0-9][0-9][0-9]) +([0-9][0-9]?):([0-9][0-9]?):"
|
|
"([0-9][0-9]?)</RideDate> *$", REG_EXTENDED))
|
|
assert(0);
|
|
|
|
if (regcomp(&rider_reg, "^<Rider><Minutes>([0-9]+\\.[0-9]+)</Minutes>"
|
|
"<TorqinLBS>([0-9]+(\\.[0-9]+)?)</TorqinLBS>"
|
|
"<Mph>([0-9]+(\\.[0-9]+)?|NaN)</Mph><Watts>([0-9]+|NaN)</Watts>"
|
|
"<Miles>([0-9]+(\\.[0-9]+)?)</Miles><Cadence>([0-9]+)</Cadence>"
|
|
"<Hrate>([0-9]+|NaN)</Hrate><ID>([0-9]+)</ID></Rider>$",
|
|
REG_EXTENDED))
|
|
assert(0);
|
|
|
|
pt_pack_header(buf);
|
|
pt_write_data(out, buf);
|
|
|
|
while (fgets(line, sizeof(line), in)) {
|
|
line[strlen(line) - 1] = '\0'; /* drop newline */
|
|
if (strcmp(line, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>") == 0) {
|
|
/* ignore it */
|
|
}
|
|
else if (strcmp(line, "<RideData>") == 0) {
|
|
/* ignore it */
|
|
}
|
|
else if (strcmp(line, "</RideData>") == 0) {
|
|
/* ignore it */
|
|
}
|
|
else if (!regexec(&date_reg, line, date_nmatch, date_pmatch, 0)) {
|
|
for (i = 1; i < date_nmatch; ++i)
|
|
line[date_pmatch[i].rm_eo] = '\0';
|
|
memset(&start_tm, 0, sizeof(start_tm));
|
|
start_tm.tm_year = atoi(line + date_pmatch[3].rm_so) - 1900;
|
|
start_tm.tm_mon = atoi(line + date_pmatch[1].rm_so) - 1;
|
|
start_tm.tm_mday = atoi(line + date_pmatch[2].rm_so);
|
|
start_tm.tm_hour = atoi(line + date_pmatch[4].rm_so);
|
|
start_tm.tm_min = atoi(line + date_pmatch[5].rm_so);
|
|
start_tm.tm_sec = atoi(line + date_pmatch[6].rm_so);
|
|
start_tm.tm_isdst = -1;
|
|
start_time = mktime(&start_tm);
|
|
assert(start_time != -1);
|
|
pt_pack_time(buf, &start_tm);
|
|
pt_write_data(out, buf);
|
|
pt_pack_config(buf, interval, rec_int, wheel_sz_mm);
|
|
pt_write_data(out, buf);
|
|
}
|
|
else if (!regexec(&rider_reg, line, rider_nmatch, rider_pmatch, 0)) {
|
|
for (i = 1; i < rider_nmatch; ++i)
|
|
line[rider_pmatch[i].rm_eo] = '\0';
|
|
mins = atof(line + rider_pmatch[1].rm_so);
|
|
nm = atof(line + rider_pmatch[2].rm_so);
|
|
if (strcmp(line + rider_pmatch[4].rm_so, "NaN") == 0)
|
|
mph = -1.0;
|
|
else
|
|
mph = atof(line + rider_pmatch[4].rm_so);
|
|
if (strcmp(line + rider_pmatch[6].rm_so, "NaN") == 0)
|
|
watts = -1.0;
|
|
else
|
|
watts = atof(line + rider_pmatch[6].rm_so);
|
|
miles = atof(line + rider_pmatch[7].rm_so);
|
|
cad = atoi(line + rider_pmatch[9].rm_so);
|
|
if (strcmp(line + rider_pmatch[10].rm_so, "NaN") == 0)
|
|
hr = 255;
|
|
else
|
|
hr = atoi(line + rider_pmatch[10].rm_so);
|
|
interval = atoi(line + rider_pmatch[11].rm_so);
|
|
if (mins - last_mins - 0.021 > 1.0 / 60.0) {
|
|
inc_time = start_time + round((mins - 0.021000001) * 60.0);
|
|
if (!localtime_r(&inc_time, &inc_tm))
|
|
assert(0);
|
|
pt_pack_time(buf, &inc_tm);
|
|
pt_write_data(out, buf);
|
|
pt_pack_config(buf, interval, rec_int, wheel_sz_mm);
|
|
pt_write_data(out, buf);
|
|
}
|
|
else if (last_interval != interval) {
|
|
pt_pack_config(buf, interval, rec_int, wheel_sz_mm);
|
|
pt_write_data(out, buf);
|
|
}
|
|
pt_pack_data(buf, wheel_sz_mm, nm, mph,
|
|
miles - last_miles, cad, hr);
|
|
pt_write_data(out, buf);
|
|
last_mins = mins;
|
|
last_interval = interval;
|
|
last_miles = miles;
|
|
}
|
|
else {
|
|
fprintf(stderr, "ERROR: line %d unrecognized: \"%s\"\n",
|
|
lineno, line);
|
|
exit(1);
|
|
}
|
|
++lineno;
|
|
}
|
|
}
|
|
|
|
static void
|
|
usage(const char *progname)
|
|
{
|
|
fprintf(stderr, "usage: %s [-o <output file>] [-r <recording interval>]"
|
|
"[-w <wheel size (mm)>] [<input file>]\n",
|
|
progname);
|
|
exit(1);
|
|
}
|
|
|
|
int
|
|
main(int argc, char *argv[])
|
|
{
|
|
int ch, i;
|
|
int wheel_sz_mm = 2096;
|
|
int rec_int = 1;
|
|
char *inname = NULL, *outname = NULL;
|
|
FILE *in, *out = NULL;
|
|
|
|
while ((ch = getopt(argc, argv, "ho:r:w:")) != -1) {
|
|
switch (ch) {
|
|
case 'o':
|
|
outname = optarg;
|
|
if (strcmp(outname, "-") == 0) {
|
|
out = stdout;
|
|
outname = "STDOUT";
|
|
}
|
|
break;
|
|
case 'r':
|
|
rec_int = atoi(optarg);
|
|
break;
|
|
case 'w':
|
|
wheel_sz_mm = atoi(optarg);
|
|
break;
|
|
case 'h':
|
|
case '?':
|
|
default:
|
|
usage(argv[0]);
|
|
}
|
|
}
|
|
argc -= optind;
|
|
argv += optind;
|
|
|
|
if (argc == 0) {
|
|
in = stdin;
|
|
inname = "STDIN";
|
|
if (outname == NULL) {
|
|
out = stdout;
|
|
outname = "STDOUT";
|
|
}
|
|
}
|
|
else {
|
|
inname = argv[0];
|
|
if ((in = fopen(inname, "r")) == NULL) {
|
|
fprintf(stderr, "Couldn't open %s for reading: %s\n",
|
|
inname, strerror(errno));
|
|
exit(1);
|
|
}
|
|
if (outname == NULL) {
|
|
outname = malloc(strlen(inname) + 5);
|
|
strcpy(outname, inname);
|
|
for (i = strlen(outname); i >= 0; --i)
|
|
if (outname[i] == '.') break;
|
|
if (i >= 0)
|
|
strcpy(outname + i + 1, "raw");
|
|
else
|
|
strcpy(outname + strlen(outname), ".raw");
|
|
}
|
|
}
|
|
|
|
if ((out == NULL) && ((out = fopen(outname, "w")) == NULL)) {
|
|
fprintf(stderr, "Couldn't open %s for writing: %s\n",
|
|
outname, strerror(errno));
|
|
exit(1);
|
|
}
|
|
|
|
pt_pack(in, out, wheel_sz_mm, rec_int);
|
|
|
|
fclose(in);
|
|
fclose(out);
|
|
|
|
return 0;
|
|
}
|
|
|