?? sinfilememorystream.pas
字號:
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 + -