diff options
Diffstat (limited to 'core/parse-xml.c')
-rw-r--r-- | core/parse-xml.c | 189 |
1 files changed, 103 insertions, 86 deletions
diff --git a/core/parse-xml.c b/core/parse-xml.c index ece85022b..303f974ed 100644 --- a/core/parse-xml.c +++ b/core/parse-xml.c @@ -43,9 +43,13 @@ struct dive_table *target_table = NULL; * Return value: length of the trimmed string, excluding the terminal 0x0 byte * The original pointer (buffer) remains valid after this function has been called * and points to the trimmed string */ -int trimspace(char *buffer) { +int trimspace(char *buffer) +{ int i, size, start, end; size = strlen(buffer); + + if (!size) + return 0; for(start = 0; isspace(buffer[start]); start++) if (start >= size) return 0; // Find 1st character following leading whitespace for(end = size - 1; isspace(buffer[end]); end--) // Find last character before trailing whitespace @@ -3204,6 +3208,18 @@ extern int divinglog_cylinder(void *handle, int columns, char **data, char **col return 0; } +static int atoi_n(char *ptr, unsigned int len) +{ + if (len < 10) { + char buf[10]; + + memcpy(buf, ptr, len); + buf[len] = 0; + return atoi(buf); + } + return 0; +} + extern int divinglog_profile(void *handle, int columns, char **data, char **column) { (void) handle; @@ -3211,8 +3227,9 @@ extern int divinglog_profile(void *handle, int columns, char **data, char **colu (void) column; int sinterval = 0; - unsigned long i, len, lenprofile2 = 0; - char *ptr, temp[4], pres[5], hbeat[4], stop[4], stime[4], ndl[4], ppo2_1[4], ppo2_2[4], ppo2_3[4], cns[5], setpoint[3]; + unsigned long time; + int len1, len2, len3, len4, len5; + char *ptr1, *ptr2, *ptr3, *ptr4, *ptr5; short oldcyl = -1; /* We do not have samples */ @@ -3252,54 +3269,74 @@ extern int divinglog_profile(void *handle, int columns, char **data, char **colu * */ - len = strlen(data[1]); + ptr1 = data[1]; + ptr2 = data[2]; + ptr3 = data[3]; + ptr4 = data[4]; + ptr5 = data[5]; + len1 = strlen(ptr1); + len2 = ptr2 ? strlen(ptr2) : 0; + len3 = ptr3 ? strlen(ptr3) : 0; + len4 = ptr4 ? strlen(ptr4) : 0; + len5 = ptr5 ? strlen(ptr5) : 0; + + time = 0; + while (len1 >= 12) { + sample_start(); - if (data[2]) - lenprofile2 = strlen(data[2]); + cur_sample->time.seconds = time; + cur_sample->in_deco = ptr1[5] - '0' ? true : false; + cur_sample->depth.mm = atoi_n(ptr1, 5) * 10; - for (i = 0, ptr = data[1]; i * 12 < len; ++i) { - sample_start(); + if (len2 >= 11) { + int temp = atoi_n(ptr2, 3); + int pressure = atoi_n(ptr2+3, 4); + int tank = atoi_n(ptr2+7, 1); + int rbt = atoi_n(ptr2+8, 3) * 60; - cur_sample->time.seconds = sinterval * i; - cur_sample->in_deco = ptr[5] - '0' ? true : false; - ptr[5] = 0; - cur_sample->depth.mm = atoi(ptr) * 10; + cur_sample->temperature.mkelvin = C_to_mkelvin(temp / 10); + cur_sample->pressure[0].mbar = pressure * 100; + if (oldcyl != tank) { + struct gasmix *mix = &cur_dive->cylinder[tank].gasmix; + int o2 = get_o2(mix); + int he = get_he(mix); - if (i * 11 < lenprofile2) { - memcpy(temp, &data[2][i * 11], 3); - cur_sample->temperature.mkelvin = C_to_mkelvin(atoi(temp) / 10); - } + event_start(); + cur_event.time.seconds = time; + strcpy(cur_event.name, "gaschange"); - if (data[2]) { - memcpy(pres, &data[2][i * 11 + 3], 4); - cur_sample->pressure[0].mbar = atoi(pres) * 100; - } + o2 = (o2 + 5) / 10; + he = (he + 5) / 10; + cur_event.value = o2 + (he << 16); - if (data[3] && strlen(data[3])) { - memcpy(hbeat, &data[3][i * 14 + 8], 3); - cur_sample->heartbeat = atoi(hbeat); - } + event_end(); + oldcyl = tank; + } - if (data[4] && strlen(data[4])) { - memcpy(stop, &data[4][i * 9 + 6], 3); - cur_sample->stopdepth.mm = atoi(stop) * 1000; + ptr2 += 11; len2 -= 11; + } - memcpy(stime, &data[4][i * 9 + 3], 3); - cur_sample->stoptime.seconds = atoi(stime) * 60; + if (len3 >= 14) { + cur_sample->heartbeat = atoi_n(ptr3+8, 3); + ptr3 += 14; len3 -= 14; + } + if (len4 >= 9) { /* * Following value is NDL when not in deco, and * either 0 or TTS when in deco. */ - - memcpy(ndl, &data[4][i * 9 + 0], 3); - if (cur_sample->in_deco == false) - cur_sample->ndl.seconds = atoi(ndl) * 60; - else if (atoi(ndl)) - cur_sample->tts.seconds = atoi(ndl) * 60; - - if (cur_sample->in_deco == true) + int val = atoi_n(ptr4, 3); + if (cur_sample->in_deco) { cur_sample->ndl.seconds = 0; + if (val) + cur_sample->tts.seconds = val * 60; + } else { + cur_sample->ndl.seconds = val * 60; + } + cur_sample->stoptime.seconds = atoi_n(ptr4+3, 3) * 60; + cur_sample->stopdepth.mm = atoi_n(ptr4+6, 3) * 1000; + ptr4 += 9; len4 -= 9; } /* @@ -3316,24 +3353,25 @@ extern int divinglog_profile(void *handle, int columns, char **data, char **colu * 1.12 bar, 1.13 bar, 1.14 bar, OTU = 154.8, CNS = 26.4, Setpoint = 1.1 */ - if (data[5] && strlen(data[5])) { - memcpy(ppo2_1, &data[5][i * 19 + 0], 3); - memcpy(ppo2_2, &data[5][i * 19 + 3], 3); - memcpy(ppo2_3, &data[5][i * 19 + 6], 3); - memcpy(cns, &data[5][i * 19 + 13], 4); - memcpy(setpoint, &data[5][i * 19 + 17], 2); - - if (atoi(ppo2_1) > 0) - cur_sample->o2sensor[0].mbar = atoi(ppo2_1) * 100; - if (atoi(ppo2_2) > 0) - cur_sample->o2sensor[1].mbar = atoi(ppo2_2) * 100; - if (atoi(ppo2_3) > 0) - cur_sample->o2sensor[2].mbar = atoi(ppo2_3) * 100; - if (atoi(cns) > 0) - cur_sample->cns = lrintf(atoi(cns) / 10.0f); - if (atoi(setpoint) > 0) - cur_sample->setpoint.mbar = atoi(setpoint) * 100; - + if (len5 >= 19) { + int ppo2_1 = atoi_n(ptr5 + 0, 3); + int ppo2_2 = atoi_n(ptr5 + 3, 3); + int ppo2_3 = atoi_n(ptr5 + 6, 3); + int otu = atoi_n(ptr5 + 9, 4); + int cns = atoi_n(ptr5 + 13, 4); + int setpoint = atoi_n(ptr5 + 17, 2); + + if (ppo2_1 > 0) + cur_sample->o2sensor[0].mbar = ppo2_1 * 100; + if (ppo2_2 > 0) + cur_sample->o2sensor[1].mbar = ppo2_2 * 100; + if (ppo2_3 > 0) + cur_sample->o2sensor[2].mbar = ppo2_3 * 100; + if (cns > 0) + cur_sample->cns = lrintf(cns / 10.0f); + if (setpoint > 0) + cur_sample->setpoint.mbar = setpoint * 100; + ptr5 += 19; len5 -= 19; } /* @@ -3346,63 +3384,42 @@ extern int divinglog_profile(void *handle, int columns, char **data, char **colu cur_sample->o2sensor[2].mbar ? 1 : 0; } - ptr += 12; sample_end(); - } - for (i = 0, ptr = data[1]; i * 12 < len; ++i) { /* Remaining bottom time warning */ - if (ptr[6] - '0') { + if (ptr1[6] - '0') { event_start(); - cur_event.time.seconds = sinterval * i; + cur_event.time.seconds = time; strcpy(cur_event.name, "rbt"); event_end(); } /* Ascent warning */ - if (ptr[7] - '0') { + if (ptr1[7] - '0') { event_start(); - cur_event.time.seconds = sinterval * i; + cur_event.time.seconds = time; strcpy(cur_event.name, "ascent"); event_end(); } /* Deco stop ignored */ - if (ptr[8] - '0') { + if (ptr1[8] - '0') { event_start(); - cur_event.time.seconds = sinterval * i; + cur_event.time.seconds = time; strcpy(cur_event.name, "violation"); event_end(); } /* Workload warning */ - if (ptr[9] - '0') { + if (ptr1[9] - '0') { event_start(); - cur_event.time.seconds = sinterval * i; + cur_event.time.seconds = time; strcpy(cur_event.name, "workload"); event_end(); } - ptr += 12; - } - for (i = 0; i * 11 < lenprofile2; ++i) { - short tank = data[2][i * 11 + 7] - '0'; - if (oldcyl != tank) { - struct gasmix *mix = &cur_dive->cylinder[tank].gasmix; - int o2 = get_o2(mix); - int he = get_he(mix); - - event_start(); - cur_event.time.seconds = sinterval * i; - strcpy(cur_event.name, "gaschange"); - - o2 = (o2 + 5) / 10; - he = (he + 5) / 10; - cur_event.value = o2 + (he << 16); - - event_end(); - oldcyl = tank; - } + ptr1 += 12; len1 -= 12; + time += sinterval; } return 0; |