Untitled
unknown
pascal
2 years ago
2.6 kB
9
Indexable
interface
TMultiStream = class(TStream)
public
// потоки
fStreams : TArray<TStream>;
// лимит размера на поток, что бы был смысл записывать в несколько потоков при записи
fSizePerStream : integer;
function Read(var Buffer; Count: Longint): Longint; override;
function Write(const Buffer; Count: Longint): Longint; override;
end;
TPartialStream = class(TStream)
public
//основой поток, так проще тестировать
fBaseStream : TStream;
//диапазон байт
fOffsetMin, fOffsetMax : integer;
function Read(var Buffer; Count: Longint): Longint; override;
function Write(const Buffer; Count: Longint): Longint; override;
end;
implementation
function TMultiStream.Read(var Buffer; Count: Longint): Longint;
begin
//просто последовательное чтение потоков
var aTotalReadCount : integer := 0;
var aBufferPos := PByte(@Buffer);
for var el in fStreams do begin
var aReadCount := el.Read(aBufferPos^, Count);
aBufferPos := aBufferPos + aReadCount;
aTotalReadCount := aTotalReadCount + aReadCount;
if aTotalReadCount >= Count then
break;
Count := Count - aReadCount;
end;
result := aTotalReadCount;
end;
function TMultiStream.Write(const Buffer; Count: Longint): Longint;
begin
//запись в потоки учитывая лимит размера на поток
var aTotalWriteCount : integer := 0;
var aBufferPos := PByte(@Buffer);
for var el in fStreams do begin
if el.Position >= fSizePerStream then
continue;
var aWriteCount := el.Write(aBufferPos^, Min(Count, Count - el.Position));
aBufferPos := aBufferPos + aWriteCount;
aTotalWriteCount := aTotalWriteCount + aWriteCount;
if aTotalWriteCount >= Count then
break;
Count := Count - aWriteCount;
end;
result := aTotalWriteCount;
end;
function TPartialStream.Read(var Buffer; Count: Longint): Longint;
begin
if fBaseStream.Position < fOffsetMin then
fBaseStream.Position := Min(fOffsetMin, fBaseStream.Size);
var aMaxCount : longint := Min(Count, fOffsetMax - fBaseStream.Position);
result := fBaseStream.Read(Buffer, aMaxCount);
end;
function TPartialStream.Write(const Buffer; Count: Longint): Longint;
begin
if fBaseStream.Position < fOffsetMin then
fBaseStream.Position := Min(fOffsetMin, fBaseStream.Size);
var aMaxCount : longint := Min(Count, fOffsetMax - fBaseStream.Position);
result := fBaseStream.Write(Buffer, aMaxCount);
end;Editor is loading...