⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 exp_buf.c

📁 ATM 网 络 协 议 实 现 源 代 码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * puts the given data in a buffer and sets it up for reading * the data.  This results in a "full" buffer with a data * blk size of given data's len */voidExpBufInstallDataInBuf PARAMS( ( buf, data, len),ExpBuf* buf _AND_char* data _AND_unsigned long int len){    buf->readError = 0;    buf->writeError = 0;    buf->blkStart = buf->dataStart = buf->curr = data;    buf->next = NULL;    buf->prev = NULL;    buf->blkEnd = buf->dataEnd = data + len;}  /* ExpBufInstallDataInBuf *//*  Buf reading and writing routines follow *//* READ * returns the next byte to be read without * advancing the pointer. No check for end of * data - this is lame */unsigned charExpBufPeekByte PARAMS( (b),ExpBuf** b){    if ((*b)->curr == (*b)->dataEnd)        (*b)->readError = 1;    return(*(*b)->curr);}  /* ExpBufPeek *//*  READ *  copy the next len chars in the buffer  to the given *  dst char string.  The curr ptr in the buffer is advanced *  appropriately */intExpBufCopy PARAMS( (dst, b, len),char* dst _AND_ExpBuf** b _AND_unsigned long int len){    unsigned long int gotLen;    int totalGotLen = 0;    char* srcPtr;    gotLen = len;    while (1)         /* optimize std path - eg only one ExpBufGetSeg needed */    {        srcPtr = ExpBufGetSeg(b, &gotLen);        memcpy(dst + totalGotLen, srcPtr, gotLen);                totalGotLen += gotLen;        if (totalGotLen >= len)            return(totalGotLen);        if (gotLen == 0)  /* eod */        {            (*b)->readError = 1;            return(totalGotLen);        }        gotLen = len - totalGotLen;    }    /* not reached */}  /* ExpBufCopy *//* * advance the curr ptr in the given buffer over the next * len bytes */voidExpBufSkip PARAMS( (b, len),ExpBuf** b _AND_unsigned long int len){    unsigned long int lenRemaining;    lenRemaining = len;    while ((len > 0) && ExpBufGetSeg(b, &lenRemaining))    {        len -= lenRemaining;        if (lenRemaining == 0)        {            (*b)->readError = 1;            return;        }        lenRemaining = len;    }}  /* ExpBufSkip *//*   READ *   returns a ptr to the next "len" bytes (contiguous).   *   if "len" is greater than the available contiguous bytes *   len is set the the number of contig. bytes the returned *   ptr references. Subsequent call to ExpBufGetSeg or other ExpBufGet *   routines will return ptrs to the following bytes (ie curr is advanced). *   Changes *b to pt to the next buffer and sets curr for the *   that buffer to dataStart if the current one has been totally read. * *   if the value returned in the len param is zero or the  *   returned char* is NULL then at end of data (eod) * */char*ExpBufGetSeg PARAMS( (b, len),ExpBuf** b _AND_unsigned long int* len){    int bytesLeft;    char* retVal;    if (ExpBufAtEod(*b))    {        *len = 0;        return(NULL);    }    bytesLeft = (*b)->dataEnd - (*b)->curr;    retVal = (*b)->curr;    /* check for "buffer fault" */    if ( bytesLeft <= *len)    {        *len = bytesLeft;        if ((*b)->next != NULL)        {            *b = (*b)->next;            /* get next buffer with valid data */            while ( ((*b)->next != NULL) && ExpBufHasNoData(*b) )                *b = (*b)->next;            /* reset current pointer to beggining of data if nec */            (*b)->curr = (*b)->dataStart;        }        else            (*b)->curr += *len;    }    else        (*b)->curr += *len;    return(retVal); }  /* ExpBufGetSeg *//* *   WRITE *   Copies len bytes from the data pointer into the given buffer  * *   FILLS EXP_BUFFERS BACKWARDS! from the end of the data to the beginning *   LINKS BUFFERS BACKWARDS! if a buf is full it allocs another an *                            puts it at the HEAD of the buffer list * *   changes *b to pt to the new "prev" buffer if the current one *   has been totally filled *   Rvs is for REVERSE! * *   modifies the dataStart pointer to reflect the new data */voidExpBufPutSegRvs PARAMS( (b, data, len),ExpBuf** b _AND_char* data _AND_unsigned long int len){    int bytesLeft;    ExpBuf* buf;    char* dataPtr;    buf = *b;    if (buf->writeError)        return;    bytesLeft = buf->dataStart - buf->blkStart;    dataPtr = data + len;  /* pts to end of data to be written */    /* optimize fast path */        do    {        if (bytesLeft > len) /* enough room in this buffer for write */        {            buf->dataStart -= len;            memcpy(buf->dataStart, data, len);            break; /* this is the normal exit from this loop */        }        else           {            /*             * going to fill this buffer completely,             * so alloc other one (only if one is not             * already linked in)             */            dataPtr  = dataPtr - bytesLeft;            buf->dataStart = buf->blkStart;            memcpy(buf->dataStart, dataPtr, bytesLeft);                        len -= bytesLeft;                        if (buf->prev == NULL)            {                /* alloc & insert new buf at head of buffer list */                buf = ExpBufAllocBufAndData();                if (buf == NULL)                {                    (*b)->writeError = 1;                    return;                }                buf->next = *b;                (*b)->prev = buf;            }            else                 buf = buf->prev;                        *b = buf; /* update head of list */            bytesLeft = buf->dataStart - buf->blkStart;        }    }    while (1);    /* not reached */}  /* ExpBufPutSegRvs *//* *   returns the next byte and advances the curr ptr by one. *   sets the readError flag if there is no byte to read *   (ie at end of data) */unsigned charExpBufGetByte PARAMS( (b),ExpBuf** b){    unsigned char retVal;     if (ExpBufAtEod(*b))    {        (*b)->readError = 1;        return((unsigned char)0);    }    retVal = *(*b)->curr++;    /* "buffer fault" - if end of this buf, go on to next, if any */    if ( ExpBufAtEod(*b) && ((*b)->next != NULL))    {        *b = (*b)->next;        /* get next buffer with valid data */        while ( ((*b)->next != NULL) && ExpBufHasNoData(*b) )            *b = (*b)->next;        /* reset current pointer to beggining of data if nec */        (*b)->curr = (*b)->dataStart;    }    return(retVal);    }  /* ExpBufGetByte *//* WRITE * Puts a single octet into the buffer * writes in reverse.  * allocates new buffers as nec - may change * (*b) to new buffer since writing backwards */voidExpBufPutByteRvs PARAMS( (b, byte),ExpBuf** b _AND_unsigned char byte){    ExpBuf* new;    if ((*b)->writeError)        return;    *(--(*b)->dataStart) = byte;    /*     * check if buffer is full and alloc new one if nec     * and insert it before this one since writing backwards     */    if (ExpBufFull(*b))    {        if ((*b)->prev == NULL)        {            /*             * no prev buf so alloc & insert             * new buf as head of buffer list             */            new = ExpBufAllocBufAndData();            if (new == NULL)            {                (*b)->writeError = 1;                return;            }                            new->next = *b;            (*b)->prev = new;            *b = new;        }        else         {            (*b) = (*b)->prev;            ExpBufResetInWriteRvsMode(*b);        }    }} /* ExpBufPutByteRvs */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -