#include #include #include #include #include "packet.h" #include "parse_serial.h" uint8_t const * parse_int(uint8_t const * buf, int * length, int * number, int * digits) { *number = 0; *digits = 0; while (*length > 0) { *length -= 1; uint8_t c = *buf++; if (c < 0x20 || c > 0x7f) continue; switch (c) { case '0': [[fallthrough]]; case '1': [[fallthrough]]; case '2': [[fallthrough]]; case '3': [[fallthrough]]; case '4': [[fallthrough]]; case '5': [[fallthrough]]; case '6': [[fallthrough]]; case '7': [[fallthrough]]; case '8': [[fallthrough]]; case '9': *digits += 1; *number *= 10; *number += c - '0'; break; case ' ': break; default: buf--; goto exit; } } exit: return buf; } int parse_time(uint8_t const * const buf, int length, struct stopwatch_time * time) { if (length < 3) return -1; uint8_t const * bufi = buf; bufi = parse_int(bufi, &length, &time->integer_value, &time->integer_digits); if (time->integer_digits == 0) { fprintf(stderr, "invalid integer at `%c`\n", *bufi); return -1; } if (*bufi++ != '.') { fprintf(stderr, "missing decimal point: `%c`\n", *bufi); return -1; } if (length < 1) return -1; bufi = parse_int(bufi, &length, &time->fraction_value, &time->fraction_digits); if (time->fraction_digits == 0) { fprintf(stderr, "invalid fraction at `%c`\n", *bufi); return -1; } return 0; } int min(int a, int b) { return a < b ? a : b; } bool is_timer_resume(uint8_t const * const buf, int length) { return false; } uint32_t handle_line(uint8_t const * const buf, int length, struct timer_state * timer_state) { if (length == 0) { timer_state->status = TIMER_RUNNING; int ret = clock_gettime(CLOCK_MONOTONIC_RAW, &timer_state->counter.start); assert(ret != -1); timer_state->counter.offset.tv_sec = 0; timer_state->counter.offset.tv_nsec = 0; return EVENT_TYPE__TIME_START; } /*else if (is_timer_resume(buf, length)) { return true; // fixme } */ else { int ret = parse_time(buf, length, &timer_state->time); if (ret == 0) { timer_state->status = TIMER_STOPPED; return EVENT_TYPE__TIME_STOP; } } return false; } uint32_t handle_parse(uint8_t * read_buf, int length, struct parser_state * parser_state, struct timer_state * timer_state) { uint32_t type = EVENT_TYPE__INVALID; while (length > 0) { int copy_length = min(length, BUFSIZE - parser_state->offset); length -= copy_length; memcpy(&parser_state->buf[parser_state->offset], read_buf, copy_length); parser_state->offset += copy_length; while (parser_state->offset > 0) { int i = 0; while (i < parser_state->offset) { if (parser_state->buf[i] == '\r') { fprintf(stderr, "r at %d %d\n", i, parser_state->offset); type = handle_line(parser_state->buf, i, timer_state); parser_state->offset -= i + 1; assert(parser_state->offset >= 0); memmove(&parser_state->buf[0], &parser_state->buf[i + 1], parser_state->offset); break; } i++; if (i == parser_state->offset) goto exit; } } exit: continue; } return type; }