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/stream.c | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 133 insertions(+), 1 deletion(-) (limited to 'lib/stream.c') 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) -- cgit v1.2.1