📄 queue.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 + -