zoukankan      html  css  js  c++  java
  • 环形缓冲区实现类(Delphi)

      环形缓冲区的用途及原理可以去百度资料狠多的,这里就不介绍了。直接贴代码.代码分别用D7,XE2编译测试

     源码下载 http://files.cnblogs.com/lwm8246/uCircleBuffer.rar

      1 //环形缓冲区实现类
      2 //2014-03-20 16:20
      3 //QQ 287413288
      4 unit uCircleBuffer;
      5 
      6 interface
      7 
      8 uses
      9   Windows,Classes;
     10 
     11 type
     12   TCircleBuffer=class
     13   private
     14     FMS:TMemoryStream;
     15     FUserData:Pointer;
     16     function GetMemory: Pointer;
     17   protected
     18     FReadPosition:Integer;
     19     FWritePosition:Integer;
     20     FCanReadCount:Integer;
     21     FCanWrieCount:Integer;
     22   public
     23     constructor Create(const BuffSize:Integer);virtual;
     24     destructor  Destroy();override;
     25     function    Write(const Buffer;Count:Integer):integer;virtual;
     26     function    Read(var Buffer;Count:Integer):Integer;virtual;
     27   public
     28     property ReadPosition:Integer  read FReadPosition;
     29     property WritePosition:Integer read FWritePosition;
     30     property CanReadCount:Integer  read FCanReadCount;
     31     property CanWrieCount:Integer  read FCanWrieCount;
     32     property Memory:Pointer read GetMemory;
     33     property UserData:Pointer read FUserData write FUserData;
     34   end;
     35 
     36   //线程安全版本
     37   TCircleBufferThread=class(TCircleBuffer)
     38   private
     39     FCS:TRTLCriticalSection;
     40     function GetReadPosition():Integer;
     41     function GetWritePosition():Integer;
     42     function GetCanReadCount():Integer;
     43     function GetCanWrieCount():Integer;
     44   public
     45     constructor Create(const BuffSize:Integer);override;
     46     destructor  Destroy();override;
     47     function    Write(const Buffer;Count:Integer):integer;override;
     48     function    Read(var Buffer;Count:Integer):Integer;override;
     49   public
     50     property ReadPosition:Integer  read GetReadPosition;
     51     property WritePosition:Integer read GetWritePosition;
     52     property CanReadCount:Integer  read GetCanReadCount;
     53     property CanWrieCount:Integer  read GetCanWrieCount;
     54   end;
     55 
     56 implementation
     57 
     58 { TCircleBuffer }
     59 
     60 constructor TCircleBuffer.Create(const BuffSize: Integer);
     61 begin
     62   FMS := TMemoryStream.Create();
     63   FMS.Size := BuffSize;
     64   FMS.Position := 0;
     65   FWritePosition := 0;
     66   FReadPosition  := 0;
     67   FCanWrieCount  := BuffSize;
     68   FCanReadCount  := 0;
     69   //\
     70   ZeroMemory(FMS.Memory,FMS.Size);
     71 end;
     72 
     73 destructor TCircleBuffer.Destroy;
     74 begin
     75   inherited;
     76   FMS.Free();
     77 end;
     78 
     79 function TCircleBuffer.GetMemory: Pointer;
     80 begin
     81   Result := FMS.Memory;
     82 end;
     83 
     84 function TCircleBuffer.Read(var Buffer; Count: Integer): Integer;
     85 var
     86   P:PAnsiChar;
     87   Len,DataLen:Integer;
     88 begin
     89   Result := 0;
     90   //(I)
     91   if FCanReadCount <= 0 then
     92   begin
     93     Exit;
     94   end;
     95 
     96   if Count > FCanReadCount then
     97     DataLen := FCanReadCount
     98   else DataLen := Count;
     99 
    100   FMS.Position := FReadPosition mod FMS.Size;
    101   Result := FMS.Read(Buffer,DataLen);
    102   Dec(FCanReadCount,Result);
    103   Dec(Count,Result);
    104 
    105   //(II)
    106   if (Count > 0) and (FCanReadCount > 0) then //继续读
    107   begin
    108     DataLen := Count;
    109     if DataLen > FCanReadCount then DataLen := FCanReadCount;
    110     FMS.Position := 0;
    111     P := @Buffer;
    112     Inc(P,Result);
    113     Len := FMS.Read(P^,DataLen);
    114     Inc(Result,Len);
    115     Dec(FCanReadCount,Len);
    116   end;
    117 
    118   //增加可写字节数
    119   Inc(FCanWrieCount,Result);
    120   if FCanWrieCount > FMS.Size then FCanWrieCount := FMS.Size;
    121 
    122   //调整读指针位置
    123   Inc(FReadPosition,Result);
    124   if FReadPosition > FMS.Size then Dec(FReadPosition,FMS.Size);
    125 
    126 end;
    127 
    128 function TCircleBuffer.Write(const Buffer; Count: Integer): integer;
    129 var
    130   Len,DataLen:Integer;
    131   P:PAnsiChar;
    132 begin
    133   Result := 0;
    134   //(I)
    135   if FCanWrieCount <= 0 then
    136   begin
    137     Exit;
    138   end;
    139 
    140   if Count > FCanWrieCount then DataLen := FCanWrieCount else DataLen := Count;
    141   FMS.Position := FWritePosition mod FMS.Size;
    142   P := @Buffer;
    143   Result := FMS.Write(Buffer,DataLen);
    144   P := FMS.Memory;
    145   if P = nil then
    146     Exit;
    147   Dec(Count,Result);
    148   Dec(FCanWrieCount,Result);
    149   if (Count > 0) and (FCanWrieCount > 0) then
    150   begin
    151     //(II)
    152     P := @Buffer;
    153     Inc(P,Result);
    154     Len := FReadPosition  - 0;
    155     if Count > Len then DataLen := Len else DataLen := Count;
    156     FMS.Position := 0;
    157     Len := FMS.Write(P^,DataLen);
    158     Inc(Result,Len);
    159     Dec(FCanWrieCount,Len);
    160   end;
    161 
    162   //增加可读字节数
    163   Inc(FCanReadCount,Result);
    164   if FCanReadCount > FMS.Size then FCanReadCount := FMS.Size;
    165 
    166   //调整写指针位置
    167   Inc(FWritePosition,Result);
    168   if FWritePosition > FMS.Size then
    169     FWritePosition := FWritePosition - FMS.Size;
    170 end;
    171 
    172 { TCircleBufferThread }
    173 
    174 constructor TCircleBufferThread.Create(const BuffSize: Integer);
    175 begin
    176   InitializeCriticalSection(FCS);  //初始化
    177   inherited Create(BuffSize);
    178 end;
    179 
    180 destructor TCircleBufferThread.Destroy;
    181 begin
    182   DeleteCriticalSection(FCS);
    183   inherited;
    184 end;
    185 
    186 function TCircleBufferThread.GetCanReadCount: Integer;
    187 begin
    188   EnterCriticalSection(FCS);
    189   Result := FCanReadCount;
    190   LeaveCriticalSection(FCS);
    191 end;
    192 
    193 function TCircleBufferThread.GetCanWrieCount: Integer;
    194 begin
    195   EnterCriticalSection(FCS);
    196   Result := FCanWrieCount;
    197   LeaveCriticalSection(FCS);
    198 end;
    199 
    200 function TCircleBufferThread.GetReadPosition: Integer;
    201 begin
    202   EnterCriticalSection(FCS);
    203   Result := FReadPosition;
    204   LeaveCriticalSection(FCS);
    205 end;
    206 
    207 function TCircleBufferThread.GetWritePosition: Integer;
    208 begin
    209   EnterCriticalSection(FCS);
    210   Result := FWritePosition;
    211   LeaveCriticalSection(FCS);
    212 end;
    213 
    214 function TCircleBufferThread.Read(var Buffer; Count: Integer): Integer;
    215 begin
    216   EnterCriticalSection(FCS);
    217   try
    218     Result := inherited read(Buffer,Count);
    219   finally
    220     LeaveCriticalSection(FCS);
    221   end;
    222 end;
    223 
    224 function TCircleBufferThread.Write(const Buffer; Count: Integer): integer;
    225 begin
    226   EnterCriticalSection(FCS);
    227   try
    228     Result := inherited Write(Buffer,Count);
    229   finally
    230     LeaveCriticalSection(FCS);
    231   end;
    232 end;
    233 
    234 end.

    测试代码段:

      1 procedure TForm1.btn1Click(Sender: TObject);
      2 var
      3   obj:TCircleBuffer;
      4   TmpStr:AnsiString;
      5   Len:Integer;
      6   Buf:array[1..4096] of AnsiChar;
      7   ASize,APosition:Integer;
      8   P:PAnsiChar;
      9 begin
     10 
     11   obj := TCircleBuffer.Create(10);
     12   ZeroMemory(@Buf,SizeOf(Buf));
     13 
     14   TmpStr := '0123456789';
     15   Len := obj.Write(TmpStr[1],Length(TmpStr));
     16   P := Obj.Memory;
     17   if P = nil then
     18     Exit;
     19 
     20   TmpStr := 'ABCD';
     21   Len := obj.Write(TmpStr[1],Length(TmpStr));
     22   if Len < 0 then
     23     Exit;
     24   P := Obj.Memory;
     25   if P = nil then
     26     Exit;
     27 
     28   TmpStr := '0123456789';
     29   Len := obj.Read(Buf,10);
     30   if Len < 0 then
     31     Exit;
     32 
     33     P := Obj.Memory;
     34   if P = nil then
     35     Exit;
     36 
     37   Len := obj.Read(Buf,10);
     38   if Len < 0 then
     39     Exit;
     40 
     41 
     42   P := Obj.Memory;
     43   if P = nil then
     44     Exit;
     45 
     46 
     47   tmpStr := 'ABC';
     48   Len := Obj.Write(TmpStr[1],3);
     49   if Len < 0 then
     50     Exit;
     51 
     52   tmpStr := '123456#';
     53   Len := Obj.Write(TmpStr[1],Length(TmpStr));
     54   if Len < 0 then
     55     Exit;
     56 
     57 
     58   P := Obj.Memory;
     59   if P = nil then
     60     Exit;
     61 
     62 
     63   FillChar(Buf,SizeOf(Buf),$32);
     64  // ZeroMemory(@Buf,SizeOf(Buf));
     65   Len := obj.Read(Buf,3);
     66     if Len < 0 then
     67     Exit;
     68 
     69   ZeroMemory(@Buf,SizeOf(Buf));
     70   Len := obj.Read(Buf,10);
     71     if Len < 0 then
     72     Exit;
     73 
     74 
     75    P := Obj.Memory;
     76   if P = nil then
     77     Exit;
     78 
     79   TmpStr := 'AB';
     80   Len := obj.Write(TmpStr[1],2);
     81   if Len < 0 then
     82    Exit;
     83 
     84      P := Obj.Memory;
     85   if P = nil then
     86     Exit;
     87 
     88 
     89   TmpStr := 'abcdefghijklmnopqrst';
     90   Len := obj.Write(TmpStr[1],Length(TmpStr));
     91   if Len < 0 then
     92    Exit;
     93 
     94 
     95 
     96 
     97    ZeroMemory(@Buf,SizeOf(Buf));
     98   Len := obj.Read(Buf,10);
     99     if Len < 0 then
    100     Exit;
    101 
    102   if obj <> nil then
    103     obj.Free();
    104 
    105      P := Obj.Memory;
    106   if P = nil then
    107     Exit;
    108 
    109 end;
  • 相关阅读:
    [转]SVN服务器搭建和使用(二)
    [转]SVN服务器搭建和使用(一)
    BZOJ 2049 Sdoi2008 Cave 洞穴勘测
    BZOJ 1589 Usaco2008 Dec Trick or Treat on the Farm 采集糖果
    BZOJ 2796 POI2012 Fibonacci Representation
    BZOJ 2115 Wc2011 Xor
    BZOJ 3105 CQOI2013 新Nim游戏
    BZOJ 2460 Beijing2011 元素
    BZOJ 3687 简单题
    BZOJ 1068 SCOI2008 压缩
  • 原文地址:https://www.cnblogs.com/lwm8246/p/3637935.html
Copyright © 2011-2022 走看看