#include #include #include #include "packet.h" #include "bufsize.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 (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 (integer_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; } struct parser_state { uint8_t buf[BUFSIZE]; int offset; }; bool is_() { } void parse_line(uint8_t * buf, int length, struct timer_state * timer_state) { if (length == 0) { timer_state->status = COUNTER_RUNNING; int ret = clock_gettime(CLOCK_MONOTONIC, &timer_state->counter.start); timer_state->counter.offset.tv_sec = 0; timer_state->counter.offset.tv_nsec = 0; assert(ret != -1); } else if (is_) { } } void handle_parse(uint8_t * read_buf, int length, struct parser_state * parser_state, struct timer_state * timer_state) { while (length > 0) { int copy_length = min(length, BUFSIZE - state->offset); length -= copy_length; memcpy(&state->buf[state->offset], read_buf, copy_length); state->offset += copy_length; while (state->offset > 0) { int i = 0; while (i < state->offset) { if (state->buf[i] == '\r') { fprintf(stderr, "r at %d %d\n", i, state->offset); handle_line(state->buf, i); state->offset -= i + 1; assert(state->offset >= 0); memmove(&state->buf[0], &state->buf[i + 1], state->offset); break; } i++; if (i == state->offset) goto exit; } } exit: continue; } }