summaryrefslogtreecommitdiffstats
path: root/nest/a-set.c
blob: fe5598e204bde5a0c2e99186e7fa3cd3eeaab302 (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
72
73
74
75
76
77
78
79
80
81
82
83
84
/*
 *	BIRD -- Set/Community-list Operations
 *
 *	(c) 2000 Martin Mares <mj@ucw.cz>
 *	(c) 2000 Pavel Machek <pavel@ucw.cz>
 *
 *	Can be freely distributed and used under the terms of the GNU GPL.
 */

#include "nest/bird.h"
#include "nest/route.h"
#include "nest/attrs.h"
#include "lib/resource.h"
#include "lib/string.h"

void
int_set_format(struct adata *set, byte *buf, unsigned int size)
{
  u32 *z = (u32 *) set->data;
  int l = set->length / 4;
  int sp = 1;
  byte *end = buf + size - 16;

  while (l--)
    {
      if (sp)
	{
	  sp = 0;
	  *buf++ = ' ';
	}
      if (buf > end)
	{
	  strcpy(buf, "...");
	  return;
	}
      /* FIXME: should not we use same syntax as in filters (i.e. (x,y) )? */
      buf += bsprintf(buf, "%d:%d ", *z/65536, *z & 0xffff);
      z++;
    }
  *buf = 0;
}

struct adata *
int_set_add(struct linpool *pool, struct adata *list, u32 val)
{
  struct adata *res = lp_alloc(pool, list->length + sizeof(struct adata) + 4);
  res->length = list->length+4;
  * (u32 *) res->data = val;
  memcpy((char *) res->data + 4, list->data, list->length);
  return res;
}

int
int_set_contains(struct adata *list, u32 val)
{
  u32 *l = &(list->data);
  int i;
  for (i=0; i<list->length/4; i++)
    if (*l++ == val)
      return 1;
  return 0;
}

struct adata *
int_set_del(struct linpool *pool, struct adata *list, u32 val)
{
  struct adata *res;
  u32 *l, *k;
  int i;

  if (!int_set_contains(list, val))
    return list;

  res = lp_alloc(pool, list->length + sizeof(struct adata) - 4);
  res->length = list->length-4;

  l = &(list->data);
  k = &(res->data);
  for (i=0; i<list->length/4; i++)
    if (l[i] != val)
      *k++ = l[i];

  return res;
}