1 Ring buffer C
Maurizio Porrato edited this page 2018-12-03 14:58:15 +00:00
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>

struct packet_s {
    char range;
    char digits[5];
    char function;
    char status;
    char options[4];
    char eol[2];
};

void print_packet(struct packet_s *packet) {
    char *p = (char *)packet;
    int i;

    for (i=0; i<sizeof(*packet); i++, p++) {
        if ((*p & 0xf0) == 0x30)
            putc(*p, stdout);
        else
            printf("[%02x]", *p);
    }
    printf("\n");
}

static const int pkt_size = sizeof(struct packet_s);

int read_packet(struct packet_s *packet) {
    char c;
    char ring[pkt_size];
    int r, pos, shift;

    pos = 0;
    shift = pkt_size;
    for (;;) {
        r = read(STDIN_FILENO, &c, 1); 
        if (r < 1)
            return 0;
        ring[pos] = c;
        pos = (pos + 1) % pkt_size;
        if (((c & 0xf0) != 0x30) && (c != '\r') && (c != '\n'))
            shift = pkt_size;
        else if (shift > 0)
            shift--;
        if ((c == '\r') && (shift != 1))
            shift = pkt_size;
        if (c == '\n') {
            if (shift == 0) {
                memcpy((char *)packet, &ring[pos], pkt_size - pos);
                memcpy((char *)packet + pkt_size - pos, ring, pos);
                return 1;
            }
            shift = pkt_size;
        }
    }
}

int main() {
    struct packet_s packet;

    while (read_packet(&packet)) {
        print_packet(&packet);
    }

    return EXIT_SUCCESS;
}