Title: Writing Types to Streams
Question: Below is a TMemoryStream descendant that has methods for writing some common delphi types to stream. I use this for preparing streams of data for transferring via TCPIP etc.
I know this can be done by using instances of TWriter or TReader classes and associating them with a stream, but I find this class easier to use / read as it is a wrapper arround a Memory stream. Also TWriter prefixes everything written by it's type so this is a bit more memory effecient if there are lots of individual items written to the stream.
If you want to persist to file then just replace the descendant with TFileStream
This class could be expanded more to utilise the variant / variant array write to stream that I did in article http://www.delphi3000.com/articles/article_3151.asp
Answer:
unit TypeMemStream;
interface
uses
Classes;
type
TTypeMemStream = class(TMemoryStream)
public
function ReadInteger : integer;
function ReadCardinal : Cardinal;
function ReadSmallInt : Smallint;
function ReadString : string;
function ReadGUID : TGUID;
function ReadWideString : widestring;
function ReadBoolean : boolean;
function ReadFloat : extended;
function ReadSingle : single;
function ReadCurrency : currency;
function ReadDateTime : TDateTime;
procedure WriteInteger(const AValue : integer);
procedure WriteCardinal(const AValue : Cardinal);
procedure WriteSmallInt(const AValue : SmallInt);
procedure WriteString(const AString : string);
procedure WriteGUID(const AGUID : TGUID);
procedure WriteWideString(const AWideString : WideString);
procedure WriteBoolean(const ABoolean : Boolean);
procedure WriteFloat(const AValue: Extended);
procedure WriteSingle(const AValue: Single);
procedure WriteCurrency(const AValue: Currency);
procedure WriteDateTime(const AValue: TDateTime);
end;
implementation
{ TTypeMemStream }
function TTypeMemStream.ReadBoolean: boolean;
var
b : byte;
begin
ReadBuffer(b, SizeOf(b));
result := boolean(b);
end;
function TTypeMemStream.ReadCardinal: Cardinal;
begin
ReadBuffer(Result, SizeOf(Result));
end;
function TTypeMemStream.ReadCurrency: currency;
begin
ReadBuffer(Result, SizeOf(Result));
end;
function TTypeMemStream.ReadDateTime: TDateTime;
begin
ReadBuffer(Result, SizeOf(Result));
end;
function TTypeMemStream.ReadFloat: extended;
begin
ReadBuffer(Result, SizeOf(Result));
end;
function TTypeMemStream.ReadGUID: TGUID;
begin
ReadBuffer(Result, SizeOf(Result));
end;
function TTypeMemStream.ReadInteger: integer;
begin
ReadBuffer(Result, SizeOf(Result));
end;
function TTypeMemStream.ReadSingle: single;
begin
ReadBuffer(Result, SizeOf(Result));
end;
function TTypeMemStream.ReadSmallInt: Smallint;
begin
ReadBuffer(Result, SizeOf(Result));
end;
function TTypeMemStream.ReadString: string;
var
ALen : cardinal;
begin
ALen := ReadCardinal;
SetLength(Result, ALen);
if ALen 0 then
begin
ReadBuffer(Result[1], Length(Result));
end;
end;
function TTypeMemStream.ReadWideString: widestring;
Var
ALen : cardinal;
ws : Widestring;
begin
ALen := ReadCardinal;
SetLength(ws, ALen div 2);
if ALen 0 then
begin
ReadBuffer(pointer(ws)^, ALen);
end;
result := ws;
end;
procedure TTypeMemStream.WriteBoolean(const ABoolean: Boolean);
var
b : byte;
begin
b := byte(ABoolean);
WriteBuffer(b, SizeOf(b));
end;
procedure TTypeMemStream.WriteCardinal(const AValue: Cardinal);
begin
WriteBuffer(AValue, SizeOf(AValue));
end;
procedure TTypeMemStream.WriteCurrency(const AValue: Currency);
begin
WriteBuffer(AValue, SizeOf(AValue));
end;
procedure TTypeMemStream.WriteDateTime(const AValue: TDateTime);
begin
WriteBuffer(AValue, SizeOf(AValue));
end;
procedure TTypeMemStream.WriteFloat(const AValue: Extended);
begin
WriteBuffer(AValue, SizeOf(AValue));
end;
procedure TTypeMemStream.WriteGUID(const AGUID: TGUID);
begin
WriteBuffer(AGUID, SizeOf(AGUID));
end;
procedure TTypeMemStream.WriteInteger(const AValue: integer);
begin
WriteBuffer(AValue, SizeOf(AValue));
end;
procedure TTypeMemStream.WriteSingle(const AValue: Single);
begin
WriteBuffer(AValue, SizeOf(AValue));
end;
procedure TTypeMemStream.WriteSmallInt(const AValue: SmallInt);
begin
WriteBuffer(AValue, SizeOf(AValue));
end;
procedure TTypeMemStream.WriteString(Const AString: string);
var
ALen : Cardinal;
begin
ALen := Length(AString);
WriteCardinal(ALen);
Write(AString[1],ALen);
end;
procedure TTypeMemStream.WriteWideString(const AWideString: WideString);
var
ALen : cardinal;
begin
ALen := Length(AWideString)*2;
WriteCardinal(ALen);
Write(Pointer(AWideString)^,ALen);
end;
end.