开发者

To implement a fixed length buffer with head and tail pointers

I am implementing a buffer of fixed length to read or write a string开发者_Python百科 using a tail or head pointer respectively. I have the following code:

bool putBuffer(char *sMsz)
{
 int iStrLen;
 iStrLen =  strlen(sMsz);
 if(!iStrLen || iStrLen>MAX_LEN)
 return 0;
  while(iStrLen-->=0)
 {
  //if head crosses tail
   if(iBufHead==iBufTail && iBufHead!=0 && dFlag)
   {  
     while(cDebugBuf[iBufTail] != '\0')
     {
       iBufTail=iBufTail+1;
       if (iBufTail>=CBUFF_SIZE)
       iBufTail = 0;
     }
    iBufTail++;
  }
     if(iBufHead>=CBUFF_SIZE)
    {
     dFlag=1; // Used to know when buffer starts over writing prev data and meets tail on                    way
    iBufHead = 0; 
    }
    cDebugBuf[iBufHead++] = *(sMsz++);
 }
 return 1;
}

 bool  getBuffer(char *readData)
 {
    int i=0; 
  do
  {
     if(iBufTail==iBufHead)
      return 0;
     if(iBufTail>=CBUFF_SIZE)
     iBufTail = 0;
     readData[i++] = cDebugBuf[iBufTail++];
   }while(cDebugBuf[iBufTail]!='\0');
   iBufTail++;
   return 1;
}

This code works until maximum buffer is hit, when head pointer starts again, tail pointer is not placed properly.

Any suggestions in improving the code, apart from finding the bugs?


With a circular buffer, there are at least two ways to distinguish a full state from an empty one (head == tail in both those cases).

  1. Allow for one more item in the buffer than you actually need and don't ever let head advance to tail when adding (raise a "buffer full" error instead). That way, head == tail always means empty.

  2. Maintain a "free slots" variable as well as the head and tail, initialising it to the size of the buffer, decrementing it when adding and incrementing when removing. That way you can detect buffer full by the fact that it's set to zero, or buffer empty if it's set to the original size.


For option 1, something like:

def buffInit(sz):
    global buffSz = sz
    global buffData = alloc(buffSz+1)         # allow for extra slot.
    global buffHead = 0
    global buffTail = 0

def buffAdd(item):
    if (buffHead + 1) % buffSz == buffTail:   # never fill extra slot.
        return BUFFER_FULL
    buffData[buffHead] = item
    buffHead = (buffHead + 1) % buffSz
    return OK

def buffGet():
    if buffHead == buffTail:
        return BUFFER_EMPTY
    item = buffData[buffHead]
    buffHead = (buffHead + 1) % buffSz
    return item

For option 2, something like:

def buffInit(sz):
    global buffSz = sz
    global buffFree = buffSz                  # extra information.
    global buffData = alloc(buffSz)
    global buffHead = 0
    global buffTail = 0

def buffAdd(item):
    if buffFree == 0:                         # zero free slots means full.
        return BUFFER_FULL
    buffData[buffHead] = item
    buffHead = (buffHead + 1) % buffSz
    buffFree = buffFree - 1                   # keep in sync.
    return OK

def buffGet():
    if buffFree == buffSz:
        return BUFFER_EMPTY
    item = buffData[buffHead]
    buffHead = (buffHead + 1) % buffSz
    buffFree = buffFree + 1                   # keep in sync.
    return item
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜