From 4b201d46348b81bd9d59aa626c81f7457ea6ef38 Mon Sep 17 00:00:00 2001 From: paul Date: Tue, 10 Jan 2006 14:35:19 +0000 Subject: [stream] Add quad-word support and stream_resize 2006-01-10 Paul Jakma * stream.c: (stream_new) Allocate stream data as seperate object. (stream_free) free the data. (stream_resize) new function, resize stream to new size. (stream_{get,put}q*) new functions to get/put quad word size types. * stream.h: (struct stream) make data seperate from the stream. Export new stream_resize and quad-word get/put functions. --- lib/ChangeLog | 10 +++++ lib/stream.c | 134 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- lib/stream.h | 17 ++++++-- 3 files changed, 157 insertions(+), 4 deletions(-) diff --git a/lib/ChangeLog b/lib/ChangeLog index b02cc517..da0bc4ad 100644 --- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -1,3 +1,13 @@ +2006-01-10 Paul Jakma + + * stream.c: (stream_new) Allocate stream data as seperate object. + (stream_free) free the data. + (stream_resize) new function, resize stream to new size. + (stream_{get,put}q*) new functions to get/put quad word size + types. + * stream.h: (struct stream) make data seperate from the stream. + Export new stream_resize and quad-word get/put functions. + 2005-12-29 Greg Troxel * vty.c (vty_hello): add cast to quiet lint (from David Young) diff --git a/lib/stream.c b/lib/stream.c index d8c10882..4c5c44ad 100644 --- a/lib/stream.c +++ b/lib/stream.c @@ -99,11 +99,17 @@ stream_new (size_t size) return NULL; } - s = XCALLOC (MTYPE_STREAM, offsetof(struct stream, data[size])); + s = XCALLOC (MTYPE_STREAM, sizeof (struct stream)); if (s == NULL) return s; + if ( (s->data = XMALLOC (MTYPE_STREAM_DATA, size)) == NULL) + { + XFREE (MTYPE_STREAM, s); + return NULL; + } + s->size = size; return s; } @@ -112,6 +118,10 @@ stream_new (size_t size) void stream_free (struct stream *s) { + if (!s) + return; + + XFREE (MTYPE_STREAM_DATA, s->data); XFREE (MTYPE_STREAM, s); } @@ -143,6 +153,30 @@ stream_dup (struct stream *s) return (stream_copy (new, s)); } + +size_t +stream_resize (struct stream *s, size_t newsize) +{ + u_char *newdata; + STREAM_VERIFY_SANE (s); + + newdata = XREALLOC (MTYPE_STREAM_DATA, s->data, newsize); + + if (newdata == NULL) + return s->size; + + s->data = newdata; + s->size = newsize; + + if (s->endp > s->size) + s->endp = s->size; + if (s->getp > s->endp) + s->getp = s->endp; + + STREAM_VERIFY_SANE (s); + + return s->size; +} size_t stream_get_getp (struct stream *s) @@ -344,6 +378,58 @@ stream_getl (struct stream *s) return l; } + +/* Get next quad word from the stream. */ +uint64_t +stream_getq_from (struct stream *s, size_t from) +{ + u_int64_t q; + + STREAM_VERIFY_SANE(s); + + if (!GETP_VALID (s, from + sizeof (uint64_t))) + { + STREAM_BOUND_WARN (s, "get quad"); + return 0; + } + + q = ((uint64_t) s->data[from++]) << 56; + q |= ((uint64_t) s->data[from++]) << 48; + q |= ((uint64_t) s->data[from++]) << 40; + q |= ((uint64_t) s->data[from++]) << 32; + q |= ((uint64_t) s->data[from++]) << 24; + q |= ((uint64_t) s->data[from++]) << 16; + q |= ((uint64_t) s->data[from++]) << 8; + q |= ((uint64_t) s->data[from++]); + + return q; +} + +uint64_t +stream_getq (struct stream *s) +{ + uint64_t q; + + STREAM_VERIFY_SANE(s); + + if (STREAM_READABLE (s) < sizeof (uint64_t)) + { + STREAM_BOUND_WARN (s, "get quad"); + return 0; + } + + q = ((uint64_t) s->data[s->getp++]) << 56; + q |= ((uint64_t) s->data[s->getp++]) << 48; + q |= ((uint64_t) s->data[s->getp++]) << 40; + q |= ((uint64_t) s->data[s->getp++]) << 32; + q |= ((uint64_t) s->data[s->getp++]) << 24; + q |= ((uint64_t) s->data[s->getp++]) << 16; + q |= ((uint64_t) s->data[s->getp++]) << 8; + q |= ((uint64_t) s->data[s->getp++]); + + return q; +} + /* Get next long word from the stream. */ u_int32_t stream_get_ipv4 (struct stream *s) @@ -448,6 +534,30 @@ stream_putl (struct stream *s, u_int32_t l) return 4; } +/* Put quad word to the stream. */ +int +stream_putq (struct stream *s, uint64_t q) +{ + STREAM_VERIFY_SANE (s); + + if (STREAM_WRITEABLE (s) < sizeof (uint64_t)) + { + STREAM_BOUND_WARN (s, "put quad"); + return 0; + } + + s->data[s->endp++] = (u_char)(q >> 56); + s->data[s->endp++] = (u_char)(q >> 48); + s->data[s->endp++] = (u_char)(q >> 40); + s->data[s->endp++] = (u_char)(q >> 32); + s->data[s->endp++] = (u_char)(q >> 24); + s->data[s->endp++] = (u_char)(q >> 16); + s->data[s->endp++] = (u_char)(q >> 8); + s->data[s->endp++] = (u_char)q; + + return 8; +} + int stream_putc_at (struct stream *s, size_t putp, u_char c) { @@ -499,6 +609,28 @@ stream_putl_at (struct stream *s, size_t putp, u_int32_t l) return 4; } +int +stream_putq_at (struct stream *s, size_t putp, uint64_t q) +{ + STREAM_VERIFY_SANE(s); + + if (!PUT_AT_VALID (s, putp + sizeof (uint64_t))) + { + STREAM_BOUND_WARN (s, "put"); + return 0; + } + s->data[putp] = (u_char)(q >> 56); + s->data[putp + 1] = (u_char)(q >> 48); + s->data[putp + 2] = (u_char)(q >> 40); + s->data[putp + 3] = (u_char)(q >> 32); + s->data[putp + 4] = (u_char)(q >> 24); + s->data[putp + 5] = (u_char)(q >> 16); + s->data[putp + 6] = (u_char)(q >> 8); + s->data[putp + 7] = (u_char)q; + + return 8; +} + /* Put long word to the stream. */ int stream_put_ipv4 (struct stream *s, u_int32_t l) diff --git a/lib/stream.h b/lib/stream.h index 564fa3ca..d2d2e401 100644 --- a/lib/stream.h +++ b/lib/stream.h @@ -103,7 +103,7 @@ struct stream size_t getp; /* next get position */ size_t endp; /* last valid data position */ size_t size; /* size of data segment */ - unsigned char data[]; /* data pointer */ + unsigned char *data; /* data pointer */ }; /* First in first out queue structure. */ @@ -127,12 +127,19 @@ struct stream_fifo #define STREAM_DATA(S) ((S)->data) #define STREAM_REMAIN(S) STREAM_WRITEABLE((S)) -/* Stream prototypes. */ +/* Stream prototypes. + * For stream_{put,get}S, the S suffix mean: + * + * c: character (unsigned byte) + * w: word (two bytes) + * l: long (two words) + * q: quad (four words) + */ extern struct stream *stream_new (size_t); extern void stream_free (struct stream *); extern struct stream * stream_copy (struct stream *new, struct stream *src); extern struct stream *stream_dup (struct stream *); - +extern size_t stream_resize (struct stream *, size_t); extern size_t stream_get_getp (struct stream *); extern size_t stream_get_endp (struct stream *); extern size_t stream_get_size (struct stream *); @@ -150,6 +157,8 @@ extern int stream_putw (struct stream *, u_int16_t); extern int stream_putw_at (struct stream *, size_t, u_int16_t); extern int stream_putl (struct stream *, u_int32_t); extern int stream_putl_at (struct stream *, size_t, u_int32_t); +extern int stream_putq (struct stream *, uint64_t); +extern int stream_putq_at (struct stream *, size_t, uint64_t); extern int stream_put_ipv4 (struct stream *, u_int32_t); extern int stream_put_in_addr (struct stream *, struct in_addr *); extern int stream_put_prefix (struct stream *, struct prefix *); @@ -161,6 +170,8 @@ extern u_int16_t stream_getw (struct stream *); extern u_int16_t stream_getw_from (struct stream *, size_t); extern u_int32_t stream_getl (struct stream *); extern u_int32_t stream_getl_from (struct stream *, size_t); +extern uint64_t stream_getq (struct stream *); +extern uint64_t stream_getq_from (struct stream *, size_t); extern u_int32_t stream_get_ipv4 (struct stream *); #undef stream_read -- cgit v1.2.1