diff options
author | paul <paul> | 2006-01-10 14:35:19 +0000 |
---|---|---|
committer | paul <paul> | 2006-01-10 14:35:19 +0000 |
commit | 4b201d46348b81bd9d59aa626c81f7457ea6ef38 (patch) | |
tree | b841d11214e5ec8ff4904d193c5e0b7c4e741a50 /lib | |
parent | e14b7fca6279fe9dc41c8aa9816b5685952c4b19 (diff) |
[stream] Add quad-word support and stream_resize
2006-01-10 Paul Jakma <paul.jakma@sun.com>
* 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.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/ChangeLog | 10 | ||||
-rw-r--r-- | lib/stream.c | 134 | ||||
-rw-r--r-- | 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 <paul.jakma@sun.com> + + * 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 <gdt@fnord.ir.bbn.com> * 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 |