]>
git.proxmox.com Git - mirror_frr.git/blob - lib/stream.c
3 * Copyright (C) 1999 Kunihiro Ishiguro
5 * This file is part of GNU Zebra.
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
31 /*A macro to check pointers in order to not
32 go behind the allocated mem block
34 Z -- size of data to be written
37 #define CHECK_SIZE(S, Z) \
38 if (((S)->putp + (Z)) > (S)->size) \
39 (Z) = (S)->size - (S)->putp;
41 /* Stream is fixed length buffer for network output/input. */
43 /* Make stream buffer. */
45 stream_new (size_t size
)
49 s
= XCALLOC (MTYPE_STREAM
, sizeof (struct stream
));
51 s
->data
= XCALLOC (MTYPE_STREAM_DATA
, size
);
58 stream_free (struct stream
*s
)
60 XFREE (MTYPE_STREAM_DATA
, s
->data
);
61 XFREE (MTYPE_STREAM
, s
);
65 stream_get_getp (struct stream
*s
)
71 stream_get_putp (struct stream
*s
)
77 stream_get_endp (struct stream
*s
)
83 stream_get_size (struct stream
*s
)
88 /* Stream structre' stream pointer related functions. */
90 stream_set_getp (struct stream
*s
, unsigned long pos
)
96 stream_set_putp (struct stream
*s
, unsigned long pos
)
101 /* Forward pointer. */
103 stream_forward (struct stream
*s
, int size
)
108 /* Copy from stream to destination. */
110 stream_get (void *dst
, struct stream
*s
, size_t size
)
112 memcpy (dst
, s
->data
+ s
->getp
, size
);
116 /* Get next character from the stream. */
118 stream_getc (struct stream
*s
)
122 c
= s
->data
[s
->getp
];
127 /* Get next character from the stream. */
129 stream_getc_from (struct stream
*s
, unsigned long from
)
137 /* Get next word from the stream. */
139 stream_getw (struct stream
*s
)
143 w
= s
->data
[s
->getp
++] << 8;
144 w
|= s
->data
[s
->getp
++];
148 /* Get next word from the stream. */
150 stream_getw_from (struct stream
*s
, unsigned long from
)
154 w
= s
->data
[from
++] << 8;
159 /* Get next long word from the stream. */
161 stream_getl (struct stream
*s
)
165 l
= s
->data
[s
->getp
++] << 24;
166 l
|= s
->data
[s
->getp
++] << 16;
167 l
|= s
->data
[s
->getp
++] << 8;
168 l
|= s
->data
[s
->getp
++];
172 /* Get next long word from the stream. */
174 stream_get_ipv4 (struct stream
*s
)
178 memcpy (&l
, s
->data
+ s
->getp
, 4);
184 /* Copy to source to stream. */
186 stream_put (struct stream
*s
, void *src
, size_t size
)
192 memcpy (s
->data
+ s
->putp
, src
, size
);
194 memset (s
->data
+ s
->putp
, 0, size
);
197 if (s
->putp
> s
->endp
)
201 /* Put character to the stream. */
203 stream_putc (struct stream
*s
, u_char c
)
205 if (s
->putp
>= s
->size
) return 0;
207 s
->data
[s
->putp
] = c
;
209 if (s
->putp
> s
->endp
)
214 /* Put word to the stream. */
216 stream_putw (struct stream
*s
, u_int16_t w
)
218 if ((s
->size
- s
->putp
) < 2) return 0;
220 s
->data
[s
->putp
++] = (u_char
)(w
>> 8);
221 s
->data
[s
->putp
++] = (u_char
) w
;
223 if (s
->putp
> s
->endp
)
228 /* Put long word to the stream. */
230 stream_putl (struct stream
*s
, u_int32_t l
)
232 if ((s
->size
- s
->putp
) < 4) return 0;
234 s
->data
[s
->putp
++] = (u_char
)(l
>> 24);
235 s
->data
[s
->putp
++] = (u_char
)(l
>> 16);
236 s
->data
[s
->putp
++] = (u_char
)(l
>> 8);
237 s
->data
[s
->putp
++] = (u_char
)l
;
239 if (s
->putp
> s
->endp
)
245 stream_putc_at (struct stream
*s
, unsigned long putp
, u_char c
)
252 stream_putw_at (struct stream
*s
, unsigned long putp
, u_int16_t w
)
254 s
->data
[putp
] = (u_char
)(w
>> 8);
255 s
->data
[putp
+ 1] = (u_char
) w
;
260 stream_putl_at (struct stream
*s
, unsigned long putp
, u_int32_t l
)
262 s
->data
[putp
] = (u_char
)(l
>> 24);
263 s
->data
[putp
+ 1] = (u_char
)(l
>> 16);
264 s
->data
[putp
+ 2] = (u_char
)(l
>> 8);
265 s
->data
[putp
+ 3] = (u_char
)l
;
269 /* Put long word to the stream. */
271 stream_put_ipv4 (struct stream
*s
, u_int32_t l
)
273 if ((s
->size
- s
->putp
) < 4)
276 memcpy (s
->data
+ s
->putp
, &l
, 4);
279 if (s
->putp
> s
->endp
)
284 /* Put long word to the stream. */
286 stream_put_in_addr (struct stream
*s
, struct in_addr
*addr
)
288 if ((s
->size
- s
->putp
) < 4)
291 memcpy (s
->data
+ s
->putp
, addr
, 4);
294 if (s
->putp
> s
->endp
)
299 /* Put prefix by nlri type format. */
301 stream_put_prefix (struct stream
*s
, struct prefix
*p
)
305 psize
= PSIZE (p
->prefixlen
);
307 if ((s
->size
- s
->putp
) < psize
) return 0;
309 stream_putc (s
, p
->prefixlen
);
310 memcpy (s
->data
+ s
->putp
, &p
->u
.prefix
, psize
);
313 if (s
->putp
> s
->endp
)
319 /* Read size from fd. */
321 stream_read (struct stream
*s
, int fd
, size_t size
)
325 nbytes
= readn (fd
, s
->data
+ s
->putp
, size
);
335 /* Read size from fd. */
337 stream_read_unblock (struct stream
*s
, int fd
, size_t size
)
342 val
= fcntl (fd
, F_GETFL
, 0);
343 fcntl (fd
, F_SETFL
, val
|O_NONBLOCK
);
344 nbytes
= read (fd
, s
->data
+ s
->putp
, size
);
345 fcntl (fd
, F_SETFL
, val
);
355 /* Write data to buffer. */
357 stream_write (struct stream
*s
, u_char
*ptr
, size_t size
)
362 memcpy (s
->data
+ s
->putp
, ptr
, size
);
364 if (s
->putp
> s
->endp
)
369 /* Return current read pointer. */
371 stream_pnt (struct stream
*s
)
373 return s
->data
+ s
->getp
;
376 /* Check does this stream empty? */
378 stream_empty (struct stream
*s
)
380 if (s
->putp
== 0 && s
->endp
== 0 && s
->getp
== 0)
388 stream_reset (struct stream
*s
)
395 /* Write stream contens to the file discriptor. */
397 stream_flush (struct stream
*s
, int fd
)
401 nbytes
= write (fd
, s
->data
+ s
->getp
, s
->endp
- s
->getp
);
406 /* Stream first in first out queue. */
411 struct stream_fifo
*new;
413 new = XCALLOC (MTYPE_STREAM_FIFO
, sizeof (struct stream_fifo
));
417 /* Add new stream to fifo. */
419 stream_fifo_push (struct stream_fifo
*fifo
, struct stream
*s
)
422 fifo
->tail
->next
= s
;
431 /* Delete first stream from fifo. */
433 stream_fifo_pop (struct stream_fifo
*fifo
)
441 fifo
->head
= s
->next
;
443 if (fifo
->head
== NULL
)
452 /* Return first fifo entry. */
454 stream_fifo_head (struct stream_fifo
*fifo
)
460 stream_fifo_clean (struct stream_fifo
*fifo
)
465 for (s
= fifo
->head
; s
; s
= next
)
470 fifo
->head
= fifo
->tail
= NULL
;
475 stream_fifo_free (struct stream_fifo
*fifo
)
477 stream_fifo_clean (fifo
);
478 XFREE (MTYPE_STREAM_FIFO
, fifo
);