type
TBuffer = class
private
FBuffer: PChar;
FMaxBufSize: integer;
FIncreasement: integer;
FContentSize: integer;
FCapacity: integer;
function GetAsString: string;
function Enlarge(NewLen: integer): Boolean;
public
OnBufFull: procedure;
property MaxBufSize: integer read FMaxBufSize;
property ContentSize: integer read FContentSize;
property Capacity: integer read FCapacity;
property Increasement: integer read FIncreasement;
property AsString: string read GetAsString;
function WriteBuf(P: PChar; Len: integer): Boolean;
procedure ClearBuf(FreeMemory: Boolean = true);
constructor Create(MaxSize: integer = 0; IncreaseSize: integer = 32768); //ȱʡÈÝÁ¿ÉÏÏÞΪÎÞÏÞ´ó£¬ÔöÁ¿Îª32K
destructor Destroy; override;
end;
procedure HexStrToBuf(HexStr: string; var Buf: TReceiveBuffers);
function BufToHexStr(Buf: TReceiveBuffers): string;
function StrToHexStr(const s: string): string;
procedure ChangeAlarmBuffers(var Buf: TReceiveBuffers); overload;
procedure ChangeAlarmBuffers(var Buf: T2096ReceiveBuffers); overload;
implementation
uses UMain;
{ TBuffer }
procedure TBuffer.ClearBuf(FreeMemory: Boolean);
begin
if FreeMemory then begin
FreeMem(FBuffer);
FBuffer := nil;
FCapacity := 0;
end;
FContentSize := 0;
end;
constructor TBuffer.Create(MaxSize: integer; IncreaseSize: integer);
begin
FBuffer := nil;
if IncreaseSize > 0 then
FIncreasement := IncreaseSize
else
FIncreasement := 32768;
if MaxSize < 0 then
FMaxBufSize := 0
else
FMaxBufSize := MaxSize;
FContentSize := 0;
FCapacity := 0;
OnBufFull := nil;
end;
destructor TBuffer.Destroy;
begin
FreeMem(FBuffer);
inherited;
end;
function TBuffer.Enlarge(NewLen: integer): Boolean;
var
P: PChar;
Len, IncNum: integer;
begin
Result := false;
if NewLen < FContentSize then //еij¤¶ÈÎÞ·¨ÈÝÄÉÒÑÓеÄÄÚÈÝ
exit;
if (FMaxBufSize > 0) and (NewLen > FMaxBufSize) then begin
if Assigned(OnBufFull) then begin
IncNum := NewLen - FCapacity; //±£´æÔöÁ¿
OnBufFull;
if FContentSize = 0 then //Èç¹ûÓû§ÔÚ OnBufFull ʼþÖÐÒѾÇå¿ÕÁË»º³åÇø
Result := Enlarge(IncNum);
end;
exit;
end;
Len := FIncreasement * ((NewLen + FIncreasement - 1) div FIncreasement);
if (FMaxBufSize > 0) and (Len > FMaxBufSize) then
Len := FMaxBufSize;
try
GetMem(P, Len);
except
if Assigned(OnBufFull) then begin
IncNum := Len - FCapacity; //±£´æÔöÁ¿
OnBufFull;
if FContentSize = 0 then //...
Result := Enlarge(IncNum);
end;
exit;
end;
Result := true;
Move(FBuffer^, P^, FContentSize);
FreeMem(FBuffer);
FCapacity := Len;
FBuffer := P;
end;
function TBuffer.GetAsString: string;
begin
SetLength(Result, FContentSize);
Move(FBuffer^, Result[1], FContentSize);
end;
function TBuffer.WriteBuf(P: PChar; Len: integer): Boolean;
var
PC: PChar;
begin
if FContentSize + Len > FCapacity then
Result := Enlarge(FContentSize + Len)
else
Result := true;
if Result then begin
PC := FBuffer + FContentSize;
Move(P^, PC^, Len);
Inc(FContentSize, Len);
end;
end;