[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.
diff --git a/lib/ChangeLog b/lib/ChangeLog
index b02cc51..da0bc4a 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 d8c1088..4c5c44a 100644
--- a/lib/stream.c
+++ b/lib/stream.c
@@ -99,11 +99,17 @@
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 @@
void
stream_free (struct stream *s)
{
+ if (!s)
+ return;
+
+ XFREE (MTYPE_STREAM_DATA, s->data);
XFREE (MTYPE_STREAM, s);
}
@@ -143,6 +153,30 @@
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 @@
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 @@
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 @@
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 564fa3c..d2d2e40 100644
--- a/lib/stream.h
+++ b/lib/stream.h
@@ -103,7 +103,7 @@
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 @@
#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_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_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