blob: 0b5d8a23421d09d025a2bdf71eea7e81f09d855f (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
{
This file is part of the Free Component Library (FCL)
Copyright (c) 1999-2000 by Michael Van Canneyt and Florian Klaempfl
See the file COPYING.FPC, included in this distribution,
for details about the copyright.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**********************************************************************}
{$mode objfpc}
{ Fake stream that always returns empty data. Can be written to and will discard
all data.
Emulates a memorystream as far as needed: by writing past the end you can
increase its size; reading past the end gives an error}
unit nullstream;
interface
uses Classes;
type
ENullStreamError = class(EStreamError);
{ TNullStream }
TNullStream = class(THandleStream)
private
FPos : Int64;
FSize: Int64;
protected
Function GetSize : int64; override;
procedure SetSize(Const AValue: Int64); override;
function GetPosition: Int64; override;
procedure InvalidSeek; override;
public
function Read(var Buffer; Count : LongInt) : Longint; override;
function Write(const Buffer; Count : LongInt) : LongInt; override;
function Seek(const Offset: int64; Origin: TSeekOrigin): int64; override;
constructor Create;
end;
implementation
const
SInvalidOperation = 'Cannot perform this operation on a NullStream.';
Function TNullStream.GetSize : int64;
begin
Result:=FSize;
end;
procedure TNullStream.SetSize(const AValue: Int64);
begin
FSize:=AValue;
if FPos>FSize then
FPos:=FSize;
end;
function TNullStream.GetPosition: Int64;
begin
Result:=FPos;
end;
procedure TNullStream.InvalidSeek;
begin
raise ENullStreamError.Create(SInvalidOperation);
end;
function TNullStream.Read(var Buffer; Count : LongInt) : Longint;
var
RealCount: longint;
begin
if (FPos+Count)>FSize then
RealCount:=FSize-FPos
else
RealCount:=Count;
FillChar(Buffer,RealCount,0);
Result:=RealCount;
Inc(FPos,RealCount);
end;
function TNullStream.Write(const Buffer; Count : LongInt) : LongInt;
begin
Inc(FPos,Count);
// Emulate a memorystream: increase size if needed
If FPos>Fsize then
FSize:=FPos;
end;
function TNullStream.Seek(const Offset: int64; Origin: TSeekOrigin): int64;
var
DesiredPos: int64;
begin
if (Origin=soCurrent) and (Offset=0) then
Result:=FPos
else
begin
case Origin of
soCurrent: DesiredPos:=FPos+Offset;
soBeginning: DesiredPos:=Offset;
soEnd: DesiredPos:=FSize-Offset;
end;
if (DesiredPos<0) or (DesiredPos>FSize) then
InvalidSeek;
FPos:=DesiredPos;
end;
end;
constructor TNullStream.Create;
begin
inherited create(0);
FPos:=0;
FSize:=0;
end;
end.
|