{-------------------------------------------------------------------------------
  过程名:    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;