[Back to WIN-OS2 SWAG index] [Back to Main SWAG index] [Original]
{
Useful for transferring objects which have been registered to the clipboard or any global memory situation.
Also could be used to make a copy of any streamable object. Merely stream the object to memory and then
re-instantiate a new object through the use of a TStream.Get. Solves the
problem of passing objects to another program because it removes any method pointer info.
NOTE: This works only for streams which are not larger than 64K. In order
to make this work for larger streams you have to ensure that your
writes and puts (and gets and reads...) don't straddle each 64K boundary.
I haven't added the pointer math to this unit yet.
}
{ Author Robert Warren CIS ID 70303,537 }
Unit MemStream;
interface
Uses WinTypes,WinProcs, WObjects;
type
PMemStream = ^TMemStream;
TMemStream = object(TStream)
Handle: Word;
Address: Pointer;
Size: Longint; { allocated size }
Position: Longint; { current position in stream }
AllocFlags: LongInt; { flags required when allocating / reallocating }
FreeMemory: Boolean; { Flag indicating whether to free global
memory when disposing of object }
constructor Init(AllocSize: Longint; Flags: LongInt; FreeMem: Boolean);
constructor InitWithHandle(aHandle: THandle; Flags: LongInt; FreeMem: Boolean);
destructor Done; virtual;
function GetPos: Longint; virtual;
procedure Grow(howMuch: LongInt); virtual;
function GetSize: Longint; virtual;
procedure Read(var Buf; Count: Word); virtual;
procedure Write(var Buf; Count: Word); virtual;
procedure Seek(Pos: Longint); virtual;
procedure Truncate; virtual;
end;
implementation
{
creates a memory stream of given size using the flags. The FreeMem argument
is used to determine whether to delete the global block of memory when the
object is disposed of. Sometime you don't want to delete the block if for
example it has been placed in the clipboard or passed using DDE.
}
constructor TMemStream.Init(AllocSize: Longint; Flags: LongInt;FreeMem: Boolean);
begin
TStream.Init;
Handle:=GlobalAlloc( Flags, AllocSize);
Address:=GlobalLock(Handle); { so much for real mode }
Size:=AllocSize;
Position:=0;
FreeMemory:= FreeMem;
end;
{
same as above but allows for the creation of a object given an already
allocated memory block. Perhaps some data FROM a clipboard
}
constructor TMemStream.InitWithHandle(aHandle: THandle; Flags: LongInt;FreeMem: Boolean);
begin
TStream.Init;
Size:=GlobalSize(Handle);
Address:=GlobalLock(Handle);
Position:=0;
FreeMemory:= FreeMem;
end;
destructor TMemStream.Done;
begin
TStream.Done;
GlobalUnlock(Handle);
If FreeMemory then GlobalFree(Handle);
end;
function TMemStream.GetPos: LongInt;
begin
GetPos:=Position;
end;
function TMemStream.GetSize: LongInt;
begin
GetSize:=Size;
end;
procedure TMemStream.Read(var Buf; Count: Word);
var
varAddress: PChar;
stAddress: PChar;
i: LongInt;
begin
varAddress:=@Buf;
stAddress:=PChar(MakeLong(Position+LoWord(LongInt(Address)),HiWord(LongInt(Address))));
for i:=0 to Count -1 do
varAddress[i]:=stAddress[i];
inc(Position,Count);
end;
procedure TMemStream.Grow(HowMuch: LongInt);
begin
GlobalUnlock(Handle);
Inc(Size,HowMuch);
GlobalRealloc(Handle, Size, AllocFlags);
GlobalLock(Handle);
end;
procedure TMemStream.Write(var Buf; Count: Word);
var
varAddress: PChar;
stAddress: PChar;
i: LongInt;
growSize: Integer;
begin
if Position + Count >= Size then
begin
if count < 1023
then growSize:=1024
else growSize:=count + 1;
Grow(growSize);
end;
varAddress:=@Buf;
stAddress:=PChar(MakeLong(Position+LoWord(LongInt(Address)),HiWord(LongInt(Address))));
for i:=0 to Count -1 do
stAddress[i]:=varAddress[i];
inc(Position,Count);
end;
procedure TMemStream.Seek(Pos: Longint);
begin
Position:=Pos;
end;
procedure TMemStream.Truncate;
begin
GlobalUnlock(Handle);
GlobalReAlloc(Handle,Position,AllocFlags);
Address:=GlobalLock(Handle);
Size:=Position;
end;
end.
[Back to WIN-OS2 SWAG index] [Back to Main SWAG index] [Original]