parse.c 2.08 KB
Newer Older
Niels Möller's avatar
Niels Möller committed
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
/* parse.c
 *
 */

#include "parse.h"

void simple_buffer_init(struct simple_buffer *buffer,
			UINT32 capacity, UINT8 *data)
{
  buffer->capacity = capacity;
  buffer->pos = 0;
  buffer->data = data;
}

#define BUFFER_LEFT (buffer->capacity - buffer->pos)
#define HERE (buffer->data + buffer->pos)
#define ADVANCE(n) (buffer->pos  += (n))

int parse_uint32(struct simple_buffer *buffer, UINT32 *result)
{
  if (BUFFER_LEFT < 4)
    return 0;

  *result = READ_INT32(HERE);
  ADVANCE(4);
  return 1;
}

int parse_string(struct simple_buffer *buffer,
		 UINT32 *length, UINT8 **start)
{
  UINT32 l;

  if (!parse_uint32(buffer, &l))
    return 0;

  if (BUFFER_LEFT < length)
    return 0;

  *length = l;
  *start = HERE;
  ADVANCE(l);
}

/* Initializes subbuffer to parse a string from buffer */
int parse_sub_buffer(struct simple_buffer *buffer,
		     struct simple_buffer *subbuffer)
{
  UINT32 length;
  UINT8 *data;

  if (!parse_string(buffer, &length, &data))
    return 0;

  simple_buffer_init(subbuffer, length, data);
  return 1;
}

int parse_uint8(struct simple_buffer *buffer, uint8 *result)
{
  if (!LEFT)
    return 0;

  *result = HERE[0];
  ADVANCE(1);
  return 1;
}

Niels Möller's avatar
Niels Möller committed
69
int parse_bignum(struct simple_buffer *buffer, bignum result)
Niels Möller's avatar
Niels Möller committed
70
71
72
73
{
  UINT32 length;
  UINT8 *digits;

Niels Möller's avatar
Niels Möller committed
74
  if (!parse_string(buffer, &length, &digits))
Niels Möller's avatar
Niels Möller committed
75
76
    return 0;

Niels Möller's avatar
Niels Möller committed
77
78
79
  parse_bignum(result, length, digits);

  return 1;
Niels Möller's avatar
Niels Möller committed
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
}

/* Returns 1 on success, 0 on failure, and -1 at end of buffer.
 * Unknown atoms sets result to zero. */

/* NOTE: This functions record the fact that it has read to the end of
 * the buffer by setting the position to *beyond* the end of the
 * buffer. */
int parse_next_atom(struct simple_buffer *buffer, int *result)
{
  UINT32 i;

  if (buffer->pos > buffer->capacity)
    return -1;

  for(i = 0; i < left; i++)
    if (HERE[i] == ',')
      {
	*result = lookup_atom(HERE, i);
	ADVANCE[i+1];
	return 1;
      }

  *result = lookup(HERE, i);
  ADVANCE(i+1);  /* Beyond end of buffer */
  return 1;
}

/* Returns success (i.e. 1) iff there is no data left */
int parse_eod(struct simple_buffer *buffer);
{
  return !LEFT;
}