/*
    Copyright 2000 (c) by David Schweikert,
    Swiss Federal Institute of Technology,
    Computer Engineering and Networks Laboratory.
 
    TOPSY -- A Teachable Operating System.
             Implementation of a tiny and simple
             micro kernel for teaching purposes.
 
    For further information, please visit http://www.tik.ee.ethz.ch/~topsy
 
    This software is provided under the terms of the GNU General Public 
    Licence. A full copy of the GNU GPL is provided in the file COPYING 
    found in the development root of Topsy.
*/
/*
    File:                  $Source: /home/ruf/cvs_Topsy/cvs/Topsy/Net/NetBuf.h,v $
    Author(s):             
    Affiliation:           ETH Zuerich, TIK
    Version:               $Revision: 2922 $
    Creation Date:         
    Last Date of Change:   $Date: 2007-03-19 17:48:52 +0100 (Mon, 19 Mär 2007) $      by: $Author: baderma $
 
*/
#ifndef _NETBUF_H
#define _NETBUF_H

#define ALIGN 4

/* NetBufsPool */
typedef struct NetBufsPoolHdr_t
{
  struct NetBufsPoolHdr_t *prev;
  struct NetBufsPoolHdr_t *next;
  unsigned long      used;
  unsigned short     sizenr; /* use NETBUF_BUFSIZE(sizenr) to get real size. */
  unsigned short     dummy; /* align to long */
}
NetBufsPoolHdr;
typedef NetBufsPoolHdr *NetBufsPool;

/* NetBuf */
typedef struct NetBufHdr_t
{
  struct NetBufHdr_t *next;
  NetBufsPool         pool;  /* do not access!! */
  unsigned short      bufnr; /* do not access!! */
  unsigned short      size;  /* use macro */
  unsigned short      start; /* use macro */
  unsigned short      end;   /* use macro */
}
NetBufHdr; /* size: 2*4+4*2=16 bytes */
typedef NetBufHdr *NetBuf;

#define NETBUF_POOLSIZE      4096
#define NETBUF_SIZES           6  /* Number of different possible sizes.

This if for 32 bit unsigned long!! */
#define NETBUF_SIZEOFUSED        (sizeof(unsigned long)*8)

#define NETBUF_MAXBUFS(s)        (NETBUF_SIZEOFUSED >> s)
#define NETBUF_HEADERSIZE        sizeof(struct NetBufHdr_t)
#define NETBUF_DATA(netbuf)      ((char *)netbuf+(netbuf)->start)
#define NETBUF_SIZE(netbuf)      ((netbuf)->size)
#define NETBUF_START(netbuf)     ((netbuf)->start)
#define NETBUF_END(netbuf)       ((netbuf)->end)
#define NETBUF_LEN(netbuf)       ((netbuf)->end-(netbuf)->start)
#define NETBUF_HEADSPACE(netbuf) ((netbuf)->start-NETBUF_HEADERSIZE)
#define NETBUF_TAILSPACE(netbuf) ((netbuf)->size+NETBUF_HEADERSIZE-(netbuf)->end)

  /* NetBuf statistics */
  struct NetBufStats_t
  {
    unsigned short sizes[NETBUF_SIZES]
      ;
      unsigned short pools[NETBUF_SIZES];
      unsigned short usage[NETBUF_SIZES];
    };
typedef struct NetBufStats_t NetBufStats;
extern NetBufStats *netbufStats;


void netbufInit();
int  netbufAlloc(NetBuf *bufPtr, unsigned int size);
void netbufFree(NetBuf buf);
int  netbufAddHeadSpace(NetBuf *bufPtr, unsigned int len);
/* add space at the head of bufPtr */
int  netbufAddTailSpace(NetBuf *bufPtr, unsigned int len);
/* add space at the end of bufPtr */
int  netbufAddHead(NetBuf *bufPtr, NetBuf buf);
/* add buf at the head of bufPtr */
int  netbufAddTail(NetBuf *bufPtr, NetBuf buf);
/* add buf at the end of bufPtr */
unsigned int netbufLen(NetBuf buf);

void netbufTrim(NetBuf buf, unsigned int len);
/* reduce size if necessary to len */
int netbufPosition(NetBuf *buf, unsigned int *position);
/* see c file */
int netbufCopy(NetBuf *dest, NetBuf src, int pos, int len);
/* dest = src[pos..pos+len] */
int netbufClone(NetBuf *dest, NetBuf src);
/* dest == src */

#define FROM_END   0x1
#define FROM_START 0x2
int netbufChop(NetBuf *dest, unsigned int len, int options);
/* remove len bytes from dest, from start or from the end */
#define SEEK_SET 0x1
#define SEEK_END 0x2
int netbufZero(NetBuf *dest, unsigned int len, unsigned int offset);
/* zero out a part of a netbuf */
int netbufWrite(NetBuf *dest, char *databuf, unsigned int len,
                int offset, int whence);
/* write data from buf to netBuf dest */
int netbufRead(NetBuf *src, char *databuf, unsigned int *len,
               unsigned int offset, int whence);
/* read data netBuf src and write it into buf */

void netbufStatistics();

#endif
