⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sinfilememorystream.pas

📁 SinStream源码
💻 PAS
📖 第 1 页 / 共 2 页
字号:
      Position := Position + OldLen;                        //..定位到 Pos+OldLen
      GetSpace(BufLen - OldLen);                            //..获取 BufLen - OldLen空间,此时pos不变
      Position := Position - OldLen;                        //..返回原Pos 即 pos-oldlen
      Write(Buf, BufLen);                                   //..数据
    end else begin                                          //..Pos后面的长度不够 OldLen 那么就直接setsize就行了。
      Size := Position + BufLen;                            //..增加 Buflen-Size 长度
      Position := Size - BufLen;                            //..还原位置
      Write(Buf, BufLen);                                   //..写数据
    end;
  end else begin                                            //..相等 直接写入即可
    write(Buf, BufLen);
  end;
end;

function TSinFileStream.ModifyFromStream(OldLen: Dword; SM: TStream; BufLen: Dword): Boolean;
begin
  Result := (SM.Size >= BufLen + SM.Position) and (BufLen <> 0) and (SM.Position < SM.Size);
  if not Result then Exit;
  if OldLen > BufLen then begin
    Delete(OldLen - BufLen);
    Result := BufLen = CopyFrom(SM, BufLen);
  end else if OldLen < BufLen then begin
    if Size > OldLen + Position then begin
      Position := Position + OldLen;                        //..定位到 Pos+OldLen
      GetSpace(BufLen - OldLen);                            //..获取 BufLen - OldLen空间,此时pos不变
      Position := Position - OldLen;                        //..返回原Pos 即 pos-oldlen
      Result := BufLen = CopyFrom(SM, BufLen);
    end else begin                                          //..Pos后面的长度不够 OldLen 那么就直接setsize就行了。
      Size := Position + BufLen;                            //..增加 Buflen-Size 长度
      Position := Size - BufLen;                            //..还原位置
      Result := BufLen = CopyFrom(SM, BufLen);
    end;
  end else begin
    Result := BufLen = CopyFrom(SM, BufLen);
  end;
end;

{ TSinMemoryStream }

function TSinMemoryStream.CMS(CSize: Dword): DWord;
var
  MMS: TMemoryStream;
  IPos: Int64;
begin
  if (CSize = 0) or (CSize > Size - Position) then begin
    Result := 0;
    Exit;
  end;
  MMS := TMemoryStream.Create;
  IPos := Position;
  try
    with CMStream(MMS) do begin
      try
        CopyFrom(Self, CSize);
      finally
        Free;
      end;
    end;
    Position := IPos;                                       //... 回来
    GetSpace(C_Size + D_Size);
    Write(CStr, C_Size);
    Write(CSize, D_Size);
    MMS.Position := 0;
    if ModifyFromStream(CSize, MMS, MMS.Size) then
      Result := MMS.Size + C_Size + D_Size
    else Result := INVALID_VALUE;
  finally
    MMS.Free;
  end;
end;

function TSinMemoryStream.DCMS(DSize: Dword): DWord;
var
  MMS: TMemoryStream;
  IPos: Int64;
  ICount: Dword;
  Buffer: PChar;
  MStr: string[5];
begin
  if (DSize = 0) or (DSize > Size - Position) or (DSize < C_Size + D_Size) then begin
    Result := 0;
    Exit;
  end;
  IPos := Position;
  Read(MStr, C_Size);
  Read(ICount, D_Size);
  if (MStr <> CStr) then begin
    Result := INVALID_VALUE;
    Position := IPos;    
    Exit;
  end;
  MMS := TMemoryStream.Create;
  MMS.CopyFrom(Self, DSize - C_Size - D_Size);
  MMS.Position := 0;
  GetMem(Buffer, ICount);
  try
    with DCMStream(MMS) do begin
      try
        ReadBuffer(Buffer^, ICount);
      finally
        Free;
      end;
    end;
    MMS.Clear;
    MMS.Write(Buffer^, ICount);
    MMS.Position := 0;
    Position := IPos;                                       //... 回来
    if ModifyFromStream(DSize, MMS, MMS.Size) then
      Result := MMS.Size
    else Result := INVALID_VALUE;
  finally
    FreeMem(Buffer);
    MMS.Free;
  end;
end;

procedure TSinMemoryStream.Delete(OldLen: Dword);
var
  tmpBuf: array[0..$10000 - 1] of Byte;
  I, L, OldPos: Int64;
begin
  if Size < OldLen + Position then begin                    //.. 删除的过长,直接SetSize即可
    Size := Position;
  end else begin                                            // ... 将后面的移动到前面... 然后 SetSize
    I := Position;
    OldPos := Position;
    repeat
      Position := I + OldLen;                               //.. 定位到后面部分
      L := Read(tmpBuf, SizeOf(tmpBuf));                    //.. 读取到Buffer中
      Position := I;                                        //.. 定位到前面部分
      Write(tmpBuf, L);                                     //.. 写入内容
      Inc(I, L);                                            //.. 移动前面部分的位置
    until L < SizeOf(tmpBuf);                               //.. 读取的小于要读取的大小说明已经读取到结尾。
    Size := Size - OldLen;                                  //.. SetSize即可。
    Position := OldPos;
  end;
end;

procedure TSinMemoryStream.GetSpace(BufLen: Dword);
var
  tmpBuf: array[0..$10000 - 1] of Byte;                     // 64K 大小 这里有个栈的问题..
  I, L, OldPos: Int64;
begin
  if BufLen <= 0 then Exit;                                 //.. 简单判断下了..不然估计出错
  I := Size;                                                //.. 保存原始大小
  OldPos := Position;                                       //.. 保存原始位置
  Size := Size + BufLen;                                    //.. 设置新大小..将前面的后移..倒着读取..
  repeat
    if OldPos + BufLen <= I - SizeOf(tmpBuf) then
      L := SizeOf(tmpBuf)                                   //.. 读取 tmpBuf长度
    else
      L := I - OldPos;                                      //.. 读取剩余长度
    Position := I - L;                                      //.. 定位到要读取的位置
    Read(tmpBuf, L);                                        //.. 读取   L长度
    Position := I - L + BufLen;                             //.. 定位到原来读取的位置
    Write(tmpBuf, L);                                       //.. 写入   L长度
    I := I - L + BufLen;                                    //.. 向前移动..
  until L < SizeOf(tmpBuf);                                 //.. 返回到原始位置,然后写入Buf内容...
  Position := OldPos;
end;

procedure TSinMemoryStream.Insert(const Buf; BufLen: Dword);
begin
  GetSpace(BufLen);
  Write(Buf, BufLen);
end;

function TSinMemoryStream.InsertFromStream(SM: TStream; BufLen: Dword): Boolean;
begin                                                       //.. 先定位  SM.Position 然后 BufLen应该<=SM.Size
  Result := BufLen = 0;
  if Result then Exit;                                      //.. 等于0 还有什么意义,退出..
  GetSpace(BufLen);
  SM.Position := 0;
  Result := BufLen = CopyFrom(SM, BufLen);
  if not Result then Delete(BufLen);
end;

procedure TSinMemoryStream.Modify(OldLen: Dword; const Buf; BufLen: Dword);
begin
  if OldLen > BufLen then begin                             //..先删除差额,再写入
    Delete(OldLen - BufLen);
    write(Buf, BufLen);
  end else if OldLen < BufLen then begin                    //..先增加差额,再写入
    if Size > OldLen + Position then begin
      Position := Position + OldLen;                        //..定位到 Pos+OldLen
      GetSpace(BufLen - OldLen);                            //..获取 BufLen - OldLen空间,此时pos不变
      Position := Position - OldLen;                        //..返回原Pos 即 pos-oldlen
      Write(Buf, BufLen);                                   //..数据
    end else begin                                          //..Pos后面的长度不够 OldLen 那么就直接setsize就行了。
      Size := Position + BufLen;                            //..增加 Buflen-Size 长度
      Position := Size - BufLen;                            //..还原位置
      Write(Buf, BufLen);                                   //..写数据
    end;
  end else begin                                            //..相等 直接写入即可
    write(Buf, BufLen);
  end;
end;

function TSinMemoryStream.ModifyFromStream(OldLen: Dword; SM: TStream; BufLen: Dword): Boolean;
begin
  Result := (SM.Size >= BufLen + SM.Position) and (BufLen <> 0) and (SM.Position < SM.Size);
  if not Result then Exit;
  if OldLen > BufLen then begin
    Delete(OldLen - BufLen);
    Result := BufLen = CopyFrom(SM, BufLen);
  end else if OldLen < BufLen then begin
    if Size > OldLen + Position then begin
      Position := Position + OldLen;                        //..定位到 Pos+OldLen
      GetSpace(BufLen - OldLen);                            //..获取 BufLen - OldLen空间,此时pos不变
      Position := Position - OldLen;                        //..返回原Pos 即 pos-oldlen
      Result := BufLen = CopyFrom(SM, BufLen);
    end else begin                                          //..Pos后面的长度不够 OldLen 那么就直接setsize就行了。
      Size := Position + BufLen;                            //..增加 Buflen-Size 长度
      Position := Size - BufLen;                            //..还原位置
      Result := BufLen = CopyFrom(SM, BufLen);
    end;
  end else begin
    Result := BufLen = CopyFrom(SM, BufLen);
  end;
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -