73beeb19b70eca1e833ac71e6c1b44fba5102898
[rrq/rrqmisc.git] / pvector / example-pvector.c
1 #include <arpa/inet.h>
2 #include <errno.h>
3 #include <fcntl.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <sys/stat.h>
8 #include <sys/types.h>
9 #include <unistd.h>
10 #include "pvector.h"
11
12 typedef struct _ipslot {
13     char data[16];
14     unsigned int bits;
15 } ipslot;
16
17 static struct {
18     pvector data;
19     int fill;
20 } table;
21
22 #define BUFSZ 10000
23 static struct {
24     char data[ BUFSZ ];
25     int cur;
26     int end;
27 } stream;
28
29 static int readline(int fd,char **outp) {
30     for ( ;; ) {
31         char *curp = stream.data + stream.cur;
32         char *endp = stream.data + stream.end;
33         char *top = curp;
34         while  ( curp < endp ) {
35             if ( *(curp++) == '\n' ) {
36                 stream.cur = curp - stream.data;
37                 (*outp) = top;
38                 return curp - top;
39             }
40         }
41         if ( top != stream.data ) {
42             curp = stream.data;
43             while ( top < endp ) {
44                 *(curp++) = *(top++);
45             }
46             endp = curp;
47             stream.end = endp - stream.data;
48         }
49         stream.cur = 0;
50         ssize_t n = read( fd, endp, BUFSZ - stream.end );
51         if ( n <= 0 ) {
52             if ( stream.end == 0 ) {
53                 return -1; // No more data
54             }
55             (*outp) = stream.data;
56             return stream.end;
57         }
58         stream.end += n;
59     }
60     //unreachable
61 }
62
63 // Scan to NUL, CR or c. Return pointer not including character.
64 static char *scanto(char *p, char c) {
65     while ( *p && *p != '\n' && *p != c ) {
66         p++;
67     }
68     return p;
69 }
70
71 static int parse_addr(char *line,ipslot *addr) {
72     char *end = scanto( line, '\n' );
73     char *slash = scanto( line, '/' );
74     *slash = 0;
75     if ( inet_pton( AF_INET, line, addr->data ) == 0 ) {
76         addr->bits = 32;
77     } if ( inet_pton( AF_INET6, line, addr->data ) == 0 ) {
78         addr->bits = 128;
79     } else {
80         return 1;
81     }
82     if ( slash != end && sscanf( slash+1, "%u", &addr->bits ) != 1 ) {
83         return 1;
84     }
85     return 0;
86 }
87
88 static void add_entry(ipslot *tmp) {
89     ipslot *p = (ipslot *) malloc( sizeof( ipslot ) );
90     memmove( p, tmp, sizeof( ipslot ) );
91     if ( table.data.size == table.fill ) {
92         (void) pvector_resize( &table.data, table.fill + 256, 0 );
93     }
94     pvector_set( &table.data, table.fill++, p );
95 }
96
97 static void load_file(const char *filename) {
98     int fd = open( filename, O_RDONLY );
99     if ( fd < 0 ) {
100         perror( filename );
101         exit( errno );
102     }
103     char *line;
104     int n;
105     while ( ( n = readline( fd, &line ) ) >= 0 ) {
106         ipslot addr;
107         if ( parse_addr( line, &addr ) ) {
108             fprintf( stderr, "Bad address: %s\n", line );
109             continue;
110         }
111         add_entry( &addr );
112     }
113 }
114
115 static int int_reclaim(pvector *pv,int index,void *item) {
116     return 1;
117 }
118
119
120 int main(int argc,char **argv) {
121     pvector test;
122     pvector_resize( &test, 100, 0 );
123     pvector_set( &test, 5, (void*) 500 );
124     pvector_set( &test, 55, (void*) 600 );
125     //pvector_set( &test, 550, (void*) 800 );
126     pvector_resize( &test, 300, 0 );
127     pvector_set( &test, 55, (void*) 650 );
128     pvector_resize( &test, 30000, 0 );
129     pvector_set( &test, 22255, (void*) 26 );
130     pvector_resize( &test, 100, int_reclaim );
131     pvector_set( &test, 5, (void*) 2 );
132
133 #if 0
134     int i;
135     for ( i = 1; i < argc; i++ ) {
136         load_file( argv[ i ] );
137     }
138 #endif
139     return 0;
140 }