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

📄 queue.cpp

📁 lua脚本语言调用allegro游戏程序库的接口-跨平台
💻 CPP
字号:
//-----------------------------------------------------------------------------------------
//---------- made by Peter Jamr髗 2001 ----------------------------------------------------
//-----------------------------------------------------------------------------------------
//This file implements improved Queue class which will be used by MyServSockets class
//and GRPC server and client

#include <malloc.h>       
#include <string.h>       
#include "Queue.h"


#define max(a,b)  (((a) > (b)) ? (a) : (b))
#define min(a,b)  (((a) < (b)) ? (a) : (b))

//-------------------------------------------------------------------------------------------
qblock::qblock()
{
prev=NULL;
EndPointer=0;
BeginPointer=0;
}

//-------------------------------------------------------------------------------------------
qblock::~qblock()
{
EndPointer=0;
BeginPointer=0;
}

//-------------------------------------------------------------------------------------------
int qblock::IsFirstBlock()
{
//if prev==NULL then true
return (prev==NULL);
}

//-------------------------------------------------------------------------------------------
/*int qblock::IsLastBlock()
{
//if next==NULL then true
return (next==NULL);
} */

//-------------------------------------------------------------------------------------------
int qblock::IsFull()
{
return (EndPointer>=QUEUE_BLOCK_SIZE);
}

//-------------------------------------------------------------------------------------------
//this function reads up to RequestedLength bytes to block. Function returns number of bytes succesfully read.
int qblock::Read(void* output,int RequestedLength)
{
char* output_buffer= (char*) output;

int bytes_to_read= min( EndPointer-BeginPointer , RequestedLength );

if (bytes_to_read==0)
   return 0;

memcpy(output_buffer, &buffer[BeginPointer] , bytes_to_read );

BeginPointer+=bytes_to_read;

//if block is empty
if (EndPointer==BeginPointer)
   {
   EndPointer=0;
   BeginPointer=0;
   }

return bytes_to_read;
}

//-------------------------------------------------------------------------------------------
//this function behaves like read, except that it does not remove data from block
int qblock::PeekData(void* output,int RequestedLength)
{
char* output_buffer= (char*) output;

int bytes_to_read= min( EndPointer-BeginPointer , RequestedLength );

if (bytes_to_read==0)
   return 0;

memcpy(output_buffer, &buffer[BeginPointer] , bytes_to_read );

return bytes_to_read;
}


//-------------------------------------------------------------------------------------------
//this function writes to block.Function returns number of bytes succesfully written.
int qblock::Write(void* input,int RequestedLength)
{
int bytes_to_write= min( ((int)QUEUE_BLOCK_SIZE-EndPointer) , RequestedLength );

if (bytes_to_write==0)
   return 0;

memcpy( &buffer[EndPointer],input,bytes_to_write);
EndPointer+=bytes_to_write;
return bytes_to_write;
}

//-------------------------------------------------------------------------------------------
//This function returns number of bytes that are stored in block queue
int qblock::GetLength()
{
return EndPointer-BeginPointer;
}

//-------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------
Queue::Queue()
{
FirstBlock=NULL;
LastBlock=NULL;
}

//-------------------------------------------------------------------------------------------
Queue::~Queue()
{
qblock* pointer;
//delete all blocks, beginning from the end of queue, and going to begin
while(LastBlock!=NULL)
   {
   pointer=LastBlock->prev;
   delete LastBlock;
   LastBlock=pointer;
   }
}

//-------------------------------------------------------------------------------------------
//this function writes RequestedLength bytes to queue.Function returns number of bytes succesfully written.
int Queue::Write(void* input,int RequestedLength)
{
int bytes_written=0;
int bytes_written_at_this_time;

char* input_buffer= (char*) input;

if (RequestedLength<0)
   return 0;

while(bytes_written<RequestedLength)
   {
   //if there is no free place in first block then create new first block:
   if ( !FirstBlock || FirstBlock->IsFull() )
      if ( !Expand() )
         return bytes_written;

   bytes_written_at_this_time=FirstBlock->Write(&input_buffer[bytes_written],RequestedLength-bytes_written);

   bytes_written+=bytes_written_at_this_time;
   }

return bytes_written;
}


//-------------------------------------------------------------------------------------------
//if the size of the Queue is not enough when writing to queue, then Expand function is called.
//it adds new empty block at the begin of the queue
int Queue::Expand()
{
qblock* NewFirstBlock=new qblock();
if (NewFirstBlock==NULL)
   return 0;

//if queue is empty:
if (FirstBlock==NULL)
   {
   FirstBlock=NewFirstBlock;
   LastBlock=NewFirstBlock;
   }
else
   {
   //previous block for current first block will be new first block
   FirstBlock->prev=NewFirstBlock;

   //first block will be new first block
   FirstBlock=NewFirstBlock;
   }

return 1;
}


//-------------------------------------------------------------------------------------------
//this function reads up to RequestedLength bytes to buffer. Function returns number of bytes succesfully read.
int Queue::Read(void* buffer,int RequestedLength)
{
int bytes_read=0;
int bytes_read_at_this_time;

char* output_buffer= (char*) buffer;

if (RequestedLength<0)
   return 0;

while(bytes_read<RequestedLength)
   {
   //if our queue is empty then return number of bytes you have read so far
   if (LastBlock==NULL)
      return bytes_read;

   bytes_read_at_this_time=LastBlock->Read(&output_buffer[bytes_read],RequestedLength-bytes_read);

   //remove block if it is not the only one block in the queue
   if ( (bytes_read_at_this_time==0) )
      if (FirstBlock!=LastBlock)
         RemoveLastBlock();
      else
         break;

   bytes_read+=bytes_read_at_this_time;
   }

return bytes_read;
}

//-------------------------------------------------------------------------------------------
int Queue::RemoveLastBlock()
{
qblock* NewLastBlock;

if (LastBlock==NULL)
   return 0;

//if we are deleting the only one (very last) block of the queue
if (FirstBlock==LastBlock)
   {
   delete LastBlock;
   LastBlock=FirstBlock=NULL;
   }
else
   {
   NewLastBlock=LastBlock->prev;
   delete LastBlock;
   LastBlock=NewLastBlock;
   }

return 1;
}

//-------------------------------------------------------------------------------------------
int Queue::GetLength()
{
qblock* Pointer=LastBlock;
int QueueLength=0;

while(Pointer)
   {
   QueueLength+=Pointer->GetLength();
   Pointer=Pointer->prev;
   }

return QueueLength;
}

//-------------------------------------------------------------------------------------------
//This function behaves like read, except that it does not remove data from the queue
int Queue::PeekData(void* output,int RequestedLength)
{
qblock* Pointer=LastBlock;
int bytes_read=0;
char* output_buffer=(char*) output;

while(Pointer)
   {
   bytes_read+=Pointer->PeekData(&output_buffer[bytes_read],
                                    RequestedLength-bytes_read);
   Pointer=Pointer->prev;
   }

return bytes_read;
}

⌨️ 快捷键说明

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