diff options
| -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  | 
