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;
  • 相关阅读:
    cmd中输入vue ui不起作用
    win10下如何让别人访问自己的数据库,开放3306端口
    maven出现报错:Failed to execute goal on project ***** Could not resolve dependencies for project com.**.**.**:jar:0.0.1-SNAPSHOT: Could not find artifact:jar:1.0-SNAPSHOT -> [Help 1]
    vue中改变字体大小,px不起作用
    vue安装教程
    Springboot快速入门
    【POI】Excel数据导入
    【MySQL】替换件需求
    【Git】Gitlab仓库访问拒绝,SSL校验影响
    【MySQL】java.sql.SQLException: Illegal mix of collations (utf8mb4_0900_ai_ci,IMPLICIT) and (utf8mb4_general_ci,IMPLICIT) for operation '='
  • 原文地址:https://www.cnblogs.com/lwm8246/p/3637935.html
Copyright © 2011-2022 走看看