summaryrefslogtreecommitdiff
path: root/src/parser.c
blob: 54e7eccc13795a0d8cccd784adaf5c3e3b2b1d4d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

#include "include/parser.h"

int blen;

static void addbyte(struct byte *bytes, int *pos, enum btype type, char *value);
static char *getpair(uint8_t *buf, int *pos);

struct byte *parse(uint8_t *buf)
{
  char *value;
  int len = 2;
  struct byte *bytes = calloc(len, sizeof(struct byte));
  for (int i = 0, j = 0; buf[i]; ++i) {
    if (j >= len)
      len *= 2;
      bytes = realloc(bytes, len * sizeof(struct byte));
    switch (buf[i]) {
      case 250:
        value = getpair(buf, &i);
        if (value == NULL)
          addbyte(bytes, &j, ERROR, "Invalid Key-Value pair");
        else
          addbyte(bytes, &j, PAIR, value);
        break;
      case 251:
        addbyte(bytes, &j, BEGIN, NULL);
        break;
      case 254:
        addbyte(bytes, &j, END, NULL);
        break;
      default:
        addbyte(bytes, &j, ERROR, "Invalid chunk");
    }
    blen = j;
  }
  return bytes;
}

static void addbyte(struct byte *bytes, int *pos, enum btype type, char *value)
{
  bytes[*pos].type = type;
  
  if (value != NULL) {
    bytes[*pos].value = value;
  }
  else
    bytes[*pos].value = NULL;
  
  (*pos)++;
}

static char *getpair(uint8_t *buf, int *pos)
{
  int i;
  for (i = *pos + 1; buf[i] != 250 && buf[i] != 254 && buf[i]; ++i)
    ;
  if (buf[i] != 250 && buf[i] != 254)
    return NULL;

  char *pair = calloc(i - *pos, sizeof(char));
  int j;
  for (j = *pos + 1; j < i; ++j)
    pair[j - (*pos + 1)] = buf[j];
  pair[j - (*pos + 1)] = '\0';
  *pos = i - 1;
  return pair;
}