destructor TRingBuffer.Destory; begin DeleteCriticalSection(FCritical); inherited Destroy; end;
procedure TRingBuffer.Release(); begin if FIsCritical then begin LeaveCriticalSection(FCritical); end; end;
function TRingBuffer.CopyBuffer(var Buffer; Count: Longint):Longint; //复制数据 var Li_RemainCount,Litemp : Integer; tempbuf:array[0..MAX_BUFFER_LEN] of Char; Datacount:Integer; begin try Result := 0; Require(); Datacount := GetDataCount(); //获取实际数据量 if (Datacount <= 0) or ( Count = 0 ) then //无数据可读的情况 begin Result := 0; Exit; end; FillChar(tempbuf,MAX_BUFFER_LEN-1,0); if Datacount >= Count then //有足够数据可读 begin if FWritePos > FReadPos then begin Move(FBuffer[FReadPos],Buffer,Count); Result := Count; FisWrap := false; end else begin //先判断尾部剩余空间有多少可读数据 Li_RemainCount := FBufferLen - FReadPos; //到缓冲区尾部还剩的缓冲量 if Count > Li_RemainCount then //尾部剩余数据都可读,把尾部数据全部读出 begin Move(FBuffer[FReadPos],tempbuf,Li_RemainCount); //暂存数据到临时buf Litemp := Count - Li_RemainCount; //剩余要读的数据 Move(FBuffer[0],tempbuf[Li_RemainCount],Litemp); //从头部读取剩余数据 Move(tempbuf,Buffer,Count); Result := Count; FisWrap := false; end else begin //当可用数据不到尾部,则直接读取 Move(FBuffer[FReadPos],tempbuf,Count); //暂存数据到临时buf Move(tempbuf,Buffer,Count); Result := Count; FisWrap := True; end; end; end else begin //无足够数据可读,可读取剩余数据 if FWritePos > FReadPos then begin Move(FBuffer[FReadPos],Buffer,Datacount); //暂存数据到临时buf Result := Datacount; FisWrap := false; end else begin //先判断尾部剩余空间有多少可读数据 Li_RemainCount := FBufferLen - FReadPos; //到缓冲区尾部还剩的缓冲量
function TRingBuffer.ReSet():Boolean; begin FReadPos := 0; FWritePos := 0; FIsCritical := False; FisWrap := False; //是否返回头部 fillchar(FBuffer[0],FBufferLen-1,0); Result := True; end;
procedure TRingBuffer.Require(); begin if FIsCritical then begin EnterCriticalSection(FCritical); end; end;
{------------------------------------------------------------------------------- 过程名: Readbuffer 作者: 黄健 日期: 2007.08.25 参数: var Buffer 需要返回的数据; Count: Integer 需要读取的数据 返回值: Longint类型, 返回实际读取的数据量 <=0 表示读取错误或缓冲区空 -------------------------------------------------------------------------------} function TRingBuffer.Readbuffer(var Buffer; Count: Integer): Longint; var Li_RemainCount,Litemp : Integer; tempbuf:array[0..MAX_BUFFER_LEN] of Char; Datacount:Integer; begin try Result := -1; Require(); //if (Count < 0) or (Count > FBufferLen) then Exit;
Datacount := GetDataCount(); //获取实际数据量 if (Datacount <= 0) or ( Count = 0 ) then //无数据可读的情况 begin Result := 0; Exit; end; FillChar(tempbuf,MAX_BUFFER_LEN-1,0); if Datacount >= Count then //有足够数据可读 begin if FWritePos > FReadPos then begin Move(FBuffer[FReadPos],Buffer,Count); Inc(FReadPos,Count); Result := Count; FisWrap := false; end else begin //先判断尾部剩余空间有多少可读数据 Li_RemainCount := FBufferLen - FReadPos; //到缓冲区尾部还剩的缓冲量 if Count > Li_RemainCount then //尾部剩余数据都可读,把尾部数据全部读出 begin Move(FBuffer[FReadPos],tempbuf,Li_RemainCount); //暂存数据到临时buf Litemp := Count - Li_RemainCount; //剩余要读的数据 Move(FBuffer[0],tempbuf[Li_RemainCount],Litemp); //从头部读取剩余数据 FReadPos := Litemp; Move(tempbuf,Buffer,Count); Result := Count; FisWrap := false; end else begin //当可用数据不到尾部,则直接读取 Move(FBuffer[FReadPos],tempbuf,Count); //暂存数据到临时buf Inc(FReadPos,Count); Move(tempbuf,Buffer,Count); Result := Count; FisWrap := True; end; end; end else begin //无足够数据可读,可读取剩余数据 if FWritePos > FReadPos then begin Move(FBuffer[FReadPos],Buffer,Datacount); //暂存数据到临时buf Inc(FReadPos,Datacount); Result := Datacount; FisWrap := false; end else begin //先判断尾部剩余空间有多少可读数据 Li_RemainCount := FBufferLen - FReadPos; //到缓冲区尾部还剩的缓冲量
{------------------------------------------------------------------------------- 过程名: WriteBuffer 作者: 黄健 日期: 2007.08.25 参数: const Buffer; 要写入的数据 Count: Integer 要写入数据大小 返回值: Longint 返回实际写入的数据量,<=0 表示写入错误或缓冲区满 -------------------------------------------------------------------------------} function TRingBuffer.WriteBuffer(const Buffer; Count: Integer): Longint; var Li_RemainCount,Litemp : Integer; tempbuf:array[0..MAX_BUFFER_LEN] of Char; EmptyCount:Integer; begin try Require(); EmptyCount := GetEmptyCount(); //获取可写入的数据大小 if (Count < 0) or (Count > FBufferLen) then begin Result := -1; Exit; end;
if (EmptyCount <=0) then //无数据可写 begin Result := 0; Exit; end;
//如果写入的缓冲区超过尾部,就跳回头部写入 if EmptyCount >= Count then begin if FWritePos < FReadPos then begin Move(Buffer,FBuffer[FWritePos],Count); Inc(FWritePos,Count); Result := Count; FisWrap := True; end else begin //判断是否到末尾,还有足够缓冲 Li_RemainCount := FBufferLen - FWritePos; if (Li_RemainCount >= Count ) then begin Move(Buffer,FBuffer[FWritePos],Count); Inc(FWritePos,Count); Result := Count; FisWrap := False; end else begin //末尾缓冲不够,返回头部读取 Litemp :=Count - Li_RemainCount ; //尾部无法写入返回头部写入的数据 FillChar(tempbuf,MAX_BUFFER_LEN-1,0); Move(Buffer,tempbuf,Count); //暂存数据到临时buf Move(tempbuf,FBuffer[FWritePos],Li_RemainCount); FWritePos := Litemp; Move(tempbuf[Li_RemainCount],FBuffer[0],Litemp); //返回头部写入剩余的数据 Result := Count; FisWrap := false; end; end; end else begin //缓冲区不足以写入全部数据,可以写入部分数据 if FWritePos < FReadPos then begin Result := FReadPos - FWritePos; Move(Buffer,FBuffer[FWritePos],Result); Inc(FWritePos,Result); FisWrap := True; end else begin //判断是否到末尾,还有足够缓冲 Li_RemainCount := FBufferLen - FWritePos; FillChar(tempbuf,MAX_BUFFER_LEN-1,0); Move(Buffer,tempbuf,Count); //暂存数据到临时buf Move(tempbuf,FBuffer[FWritePos],Li_RemainCount); if FReadPos > 0 then begin FWritePos := FReadPos; Move(tempbuf[Li_RemainCount],FBuffer[0],FReadPos); //返回头部写入剩余的数据 Result := Li_RemainCount + FReadPos; FisWrap := true; end else begin Inc(FWritePos,Li_RemainCount); Result := Li_RemainCount; FisWrap := False; end; end; end; finally Release(); end; end;
{------------------------------------------------------------------------------- 过程名: TRingBuffer.GetDataCount 作者: 黄健 日期: 2007.08.25 参数: 无 返回值: Longint 返回当前可读的数据量 -------------------------------------------------------------------------------} function TRingBuffer.GetDataCount: Longint; begin try Require(); if (FWritePos = 0) and (FReadPos = FWritePos) then begin Result := 0; Exit; end; if (FWritePos > FReadPos ) then begin Result := FWritePos - FReadPos; end else if FWritePos < FReadPos then begin Result := FBufferLen - FReadPos + FWritePos; end else if FWritePos = FReadPos then begin if FisWrap then Result := FBufferLen else Result := 0; end; finally Release(); end; end;
{------------------------------------------------------------------------------- 过程名: TRingBuffer.GetEmptyCount 作者: 黄健 日期: 2007.08.25 参数: 无 返回值: Longint 返回当前可写的数据量 -------------------------------------------------------------------------------} function TRingBuffer.GetEmptyCount: Longint; begin try Require(); if FWritePos > FReadPos then Result := FBufferLen - FWritePos + FReadPos else if FWritePos < FReadPos then Result := FReadPos - FWritePos else if FWritePos = FReadPos then begin if FisWrap then Result := 0 else Result := FBufferLen; end; finally Release(); end; end;
{------------------------------------------------------------------------------- 过程名: TRingBuffer.ResizeBuffer 作者: 黄健 日期: 2007.08.25 参数: ABufferLen: Longint 返回值: Boolean 改变缓冲区大小,返回false表示失败,true表示成功 -------------------------------------------------------------------------------} function TRingBuffer.ResizeBuffer(ABufferLen: Longint): Boolean; begin Result := False; try Require(); if ABufferLen < FBufferLen then Exit; SetLength(FBuffer,ABufferLen); FBufferLen := ABufferLen; finally Release(); end; end;
destructor TRingBufferSyn.Destory; begin CloseHandle(FSynEvent); inherited Destory(); end;
{------------------------------------------------------------------------------- 过程名: TRingBufferSyn.ReadbufferSyn 作者: 黄健 日期: 2007.08.26 参数: var Buffer; Count, TimeOut: Integer 返回值: Integer ,返回-1表示错误,-2表示超时 ,>0表示实际读取的字节 -------------------------------------------------------------------------------} function TRingBufferSyn.ReadbufferSyn(var Buffer; Count, TimeOut: Integer):Integer; var ReadCount,RemainCount,ReadPos:Integer; Abuf:array[0..MAX_BUFFER_LEN-1] of Char; ATimeOut:Integer; begin Result := -1; FillChar(Abuf,MAX_BUFFER_LEN-1,0); ReadCount := Readbuffer(Abuf,Count); if ReadCount < 0 then Exit; if ReadCount = Count then begin Move(Abuf,Buffer,Count); Result := Count; end else if ReadCount < Count then begin RemainCount := Count - ReadCount; ReadPos := ReadCount; ATimeOut := 0; while (RemainCount <= 0) do begin ReadCount := Readbuffer(Abuf[ReadPos],RemainCount); Inc(ReadPos,ReadCount); RemainCount := Count - ReadPos; //Sleep(1); Inc(ATimeOut); if ATimeOut >= TimeOut then begin Result := -2; Exit; end; end; Result := Count; end; end;
{------------------------------------------------------------------------------- 过程名: TRingBufferSyn.WriteBufferSyn 作者: 黄健 日期: 2007.08.26 参数: const Buffer; Count, TimeOut: Integer 返回值: Integer Integer ,返回-1表示错误,-2表示超时 ,>0表示实际读取的字节 -------------------------------------------------------------------------------} function TRingBufferSyn.WriteBufferSyn(const Buffer; Count, TimeOut: Integer):Integer; var WriteCount,RemainCount,WritePos:Integer; Abuf:array[0..MAX_BUFFER_LEN-1] of Char; ATimeOut:Integer; begin Result := -1; FillChar(Abuf,MAX_BUFFER_LEN-1,0); WriteCount := WriteBuffer(Buffer,Count); if WriteCount < 0 then Exit; if WriteCount = Count then begin Result := Count; end else if WriteCount < Count then begin Move(Buffer,Abuf,Count); RemainCount := Count - WriteCount; WritePos := WriteCount; ATimeOut := 0; while (RemainCount <= 0) do begin WriteCount := WriteBuffer(Abuf[WritePos],RemainCount); Inc(WritePos,WriteCount); RemainCount := Count - WritePos; //Sleep(1); Inc(ATimeOut); if ATimeOut >= TimeOut then begin Result := -2; Exit; end; end; Result := Count; end; end;