简单的缓冲区助手类

//代码修改于 ICS 网络通信控件 中的TBuff类
 
    在某些有性能要求的地方,我们会开辟一块缓冲区,也就是分配一块内存,数据在都在此内存中操作,避免频繁的内存分配释放操作。
尤其在写服务器端程序时,这点显得非常重要,如果是普通的客户端程序,本文所说的方法,就不要考虑了,毕竟是操作有些繁琐。
这个助手类的目的是提高性能,同时还有个特点,助手类内部会进行内存边界的检测,保证在往缓冲区内写数据的时候,不会发生溢出,
听过说 著名的“缓冲区溢出”攻击吧。另外一个特点是,缓冲区的大小是在创建的时候,一次分配好,而不能进行修改。目的是配合内存
池使用,减少内存碎片的产生。但类的内部提供了,动态改变缓冲区大小的功能。只不过在这里被屏蔽掉了。要恢复此功能,很简单
修改代码如下: 
 
  1 unit WSockBuf;

  2 interface

  3 uses

  4   SysUtils;

  5 type

  6   TFixedBuffer = class

  7   private

  8     FBuf      : Pointer;

  9     FBufSize  : Integer;

 10     FWrCount  : Integer;

 11     FRdCount  : Integer;

 12     procedure   SetBufSize(newSize : Integer);

 13    // function    Remove(Len : Integer) : Integer;

 14     function    Peek(var Len : Integer) : Pointer;

 15   public

 16     procedure   Clear();

 17     constructor Create(nSize : Integer=4096); virtual;

 18     destructor  Destroy; override;

 19     function    Write(Data : Pointer; Len : Integer) : Integer;

 20     function    WriteStr(const Data:string):Integer;

 21     function    Read(Data : Pointer; Len : Integer) : Integer;

 22     function    ReadStr(Len:Integer=0):string; //Len <=0,读取全部数据

 23   public

 24     property    Buf:Pointer read FBuf;

 25     property    Position:Integer read FWrCount;

 26     property    BufSize : Integer read FBufSize;// write SetBufSize;

 27   end;

 28 implementation

 29 

 30 {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}

 31 constructor TFixedBuffer.Create(nSize : Integer);

 32 begin

 33   inherited Create;

 34   FWrCount  := 0;

 35   FRdCount  := 0;

 36   SetBufSize(nSize);

 37 end;

 38 

 39 {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}

 40 destructor TFixedBuffer.Destroy;

 41 begin

 42     if Assigned(Buf) then

 43         FreeMem(Buf, FBufSize);

 44     inherited Destroy;

 45 end;

 46 

 47 {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}

 48 procedure TFixedBuffer.SetBufSize(newSize : Integer);

 49 var

 50     newBuf : Pointer;

 51 begin

 52     if newSize <= 0 then

 53         newSize := 1514;

 54     if newSize = FBufSize then

 55         Exit;

 56     if FWrCount = FRdCount then begin

 57         { Buffer is empty }

 58         if Assigned(Buf) then

 59             FreeMem(Buf, FBufSize);

 60         FBufSize := newSize;

 61         GetMem(FBuf, FBufSize);

 62     end

 63     else begin

 64         { Buffer contains data }

 65         GetMem(newBuf, newSize);

 66         Move(Buf^, newBuf^, FWrCount);

 67         if Assigned(Buf) then

 68             FreeMem(Buf, FBufSize);

 69         FBufSize := newSize;

 70         FBuf      := newBuf;

 71     end;

 72 end;

 73 

 74 {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}

 75 function TFixedBuffer.Write(Data : Pointer; Len : Integer) : Integer;

 76 var

 77     Remaining : Integer;

 78     Copied    : Integer;

 79 begin

 80     Remaining := FBufSize - FWrCount;

 81     if Remaining <= 0 then

 82         Result := 0

 83     else begin

 84         if Len <= Remaining then

 85             Copied := Len

 86         else

 87             Copied := Remaining;

 88         Move(Data^, (PChar(Buf) + FWrCount)^, Copied);

 89         FWrCount := FWrCount + Copied;

 90         Result  := Copied;

 91     end;

 92 end;

 93 

 94 {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}

 95 function TFixedBuffer.Read(Data : Pointer; Len : Integer) : Integer;

 96 var

 97     Remaining : Integer;

 98     Copied    : Integer;

 99 begin

100     Remaining := FWrCount - FRdCount;

101     if Remaining <= 0 then

102         Result := 0

103     else begin

104         if Len <= Remaining then

105             Copied := Len

106         else

107             Copied := Remaining;

108         Move((PChar(Buf) + FRdCount)^, Data^, Copied);

109         FRdCount := FRdCount + Copied;

110         if FRdCount = FWrCount then begin

111             FRdCount := 0;

112             FWrCount := 0;

113         end;

114         Result := Copied;

115     end;

116 end;

117 

118 {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}

119 function TFixedBuffer.Peek(var Len : Integer) : Pointer;

120 var

121     Remaining : Integer;

122 begin

123     Remaining := FWrCount - FRdCount;

124     if Remaining <= 0 then begin

125         Len    := 0;

126         Result := nil;

127     end

128     else begin

129         Len    := Remaining;

130         Result := Pointer(PChar(Buf) + FRdCount);

131     end;

132 end;

133 (*

134 function TFixedBuffer.Remove(Len : Integer) : Integer;

135 var

136     Remaining : Integer;

137     Removed   : Integer;

138 begin

139     Remaining := FWrCount - FRdCount;

140     if Remaining <= 0 then

141         Result := 0

142     else begin

143         if Len < Remaining then

144             Removed := Len

145         else

146             Removed := Remaining;

147         FRdCount := FRdCount + Removed;

148         if FRdCount = FWrCount then begin

149             FRdCount := 0;

150             FWrCount := 0;

151         end;

152         Result := Removed;

153     end;

154 end;

155 *)

156 {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}

157 function TFixedBuffer.WriteStr(const Data: string): Integer;

158 begin

159   Result := Write(Pointer(Data),Length(Data));

160 end;

161 function TFixedBuffer.ReadStr(Len: Integer): string;

162 begin

163   if Len <= 0 then len := system.MaxLongint;

164   Peek(Len);

165   if Len > 0 then

166   begin

167     SetLength(Result,Len);

168     Read(Pointer(Result),Len);

169   end

170   else Result := '';

171 end;

172 procedure TFixedBuffer.Clear;

173 begin

174   FWrCount  := 0;

175   FRdCount  := 0;

176 end;

 

你可能感兴趣的:(简单)