1.TWriter对象
WriteBuffer是TWriter对象定义的私有方法,它的作用是将Writer 对象内部缓冲区中的有效数据写入流中,并将FBufPos置为0。FlushBuffer对象就是用WriteBuffer方法刷新缓冲区。
procedure TWriter.WriteBuffer;
begin
FStream.WriteBuffer(FBuffer^, FBufPos);
FBufPos := 0;
end;
在SetPosition方法中,如果Value值超出了边界(FStream.Position,FStream.Position + FBufPos),就将缓冲区中的内容写入流,重新设置缓冲区在流中的相对位置;否则,就只是移动FBufPos指针。
procedure TWriter.SetPosition(Value: Longint);
var
StreamPosition: Longint;
begin
StreamPosition := FStream.Position;
{ 只清除越界的缓冲区 }
if (Value < StreamPosition) or (Value > StreamPosition + FBufPos) then
begin
WriteBuffer;
FStream.Position := Value;
end
else FBufPos := Value - StreamPosition;
end;
WriteListBegin和WriteListEnd的实现,WriteListBegin写入VaList标志,WriteListEnd写入VaNull标志。 两个方法都调用TWriter对象的WriteValue方法,该方法主要用于写入TValueType类型的值。
procedure TWriter.WriteValue(Value: TValueType);
begin
Write(Value, SizeOf(Value));
end;procedure TWriter.WriteListBegin;
begin
WriteValue(vaList);
end; procedure TWriter.WriteListEnd;
begin
WriteValue(vaNull);
end;
简单数据类型的写入
简单数据类型指的是整型、字符型、字符串型、浮点型、布尔型等。TWriter对象都定义了相应的写入方法。
WriteInteger方法将整型数据分为8位、16位和32位三种,并分别用vaInt8、vaInt16和VaInt32。
procedure TWriter.WriteInteger(Value: Longint);
begin
if (Value >= -128) and (Value <= 127) then
begin
WriteValue(vaInt8);
Write(Value, SizeOf(Shortint));
end else
if (Value >= -32768) and (Value <= 32767) then
begin
WriteValue(vaInt16);
Write(Value, SizeOf(Smallint));
end else
begin
WriteValue(vaInt32);
Write(Value, SizeOf(Longint));
end;
end;
与其它数据类型不同的是布尔型数据只使用了标志位是存储布尔值,在标志位后没有数据。字符串“True”、“False”和“nil”作为标识符传入是由于Delphi的特殊需要。如果是“True”、“False”和“nil”则写入VaTrue、VaFalse和VaNil,否则写入VaIdent标志,接着以字符串形式写入标识符。
procedure TWriter.WriteFloat(Value: Extended);
begin
WriteValue(vaExtended);
Write(Value, SizeOf(Extended));
end;
WriteString方法用于写入字符串 .Delphi的字符串类型有两种。一种长度小于256个字节,另一种长度小于65536 个字节。WriteString方法区分这两类情况存储字符串,一种设置VaStirng标志,另一种设置VaLString。然后存储字符串的长度值,最后存储字符串数据。
procedure TWriter.WriteString(const Value: string);
var
L: Integer;
begin
L := Length(Value);
if L <= 255 then
begin
WriteValue(vaString);
Write(L, SizeOf(Byte));
end else
begin
WriteValue(vaLString);
Write(L, SizeOf(Integer));
end;
Write(Pointer(Value)^, L);
end;
部件的写入:
TWriter对象中与写入部件有关的方法有WriteSignature、WritePrefix、WriteComponent、WriteDescendant和WriteRootComponent。
procedure TWriter.WriteSignature; //WriteSignature方法用于往流中写入Filer对象标签。FilerStgnature是字符串常量,其值为“TPF0”,代表对象标签。
begin
Write(FilerSignature, SizeOf(FilerSignature));
end;
WritePrefix方法用于在写入部件前写入ffInherited和ffChildPos标志,这些标志表示部件的继承特征和创建序值特征。
procedure TWriter.WritePrefix(Flags: TFilerFlags; AChildPos: Integer);
var
Prefix: Byte;
begin
if Flags <> [] then
begin
Prefix := $F0 or Byte(Flags);
Write(Prefix, SizeOf(Prefix));
if ffChildPos in Flags then WriteInteger(AChildPos); //如果ffChildPos置位,则存入部件在Owner中的创建序值 end;
end;
WriteComponent方法往流中写入部件。
procedure TWriter.WriteComponent(Component: TComponent);
function FindAncestor(const Name: string): TComponent;
begin end;
var
OldAncestor: TPersistent;
OldRootAncestor: TComponent;
AncestorComponent: TComponent;
I: Integer;
begin
OldAncestor := Ancestor;
OldRootAncestor := RootAncestor;
try
Include(Component.FComponentState, csWriting); //将控件的FComponentState置为csWriting
for I := 0 to Component.ComponentCount - 1 do //将其所拥有的控件的FComponentState置为csWriting
if csSubComponent in Component.Components[I].ComponentStyle then
Include(Component.Components[I].FComponentState, csWriting);
if Assigned(FAncestorList) then
Ancestor := FindAncestor(Component.Name);
if Assigned(FOnFindAncestor) and ((Ancestor = nil) or
(Ancestor is TComponent)) then
begin
AncestorComponent := TComponent(Ancestor);
FOnFindAncestor(Self, Component, Component.Name, AncestorComponent,
FRootAncestor);
Ancestor := AncestorComponent;
end;
Component.WriteState(Self); //写入属性
Exclude(Component.FComponentState, csWriting);//写入完后再将csWriting复位
for I := 0 to Component.ComponentCount - 1 do
if csSubComponent in Component.Components[I].ComponentStyle then
Exclude(Component.Components[I].FComponentState, csWriting);
finally
Ancestor := OldAncestor;
FRootAncestor := OldRootAncestor;
end;
end;
procedure TWriter.WriteRootComponent(Root: TComponent);//将Ancestor参数以nil值传入,调用WriteDescendant方法写入部件
begin
WriteDescendent(Root, nil);
end;
//先调用WriteSignature方法写入Filer对象标签。然后调用WriteComponent将部件Root写入流
procedure TWriter.WriteDescendent(Root: TComponent; AAncestor: TComponentbegin);
FRootAncestor := AAncestor;
FAncestor := AAncestor;
FRoot := Root;
FLookupRoot := Root;
WriteSignature;
WriteComponent(Root);
end;
procedure TStream.WriteDescendent(Instance, Ancestor: TComponent); //创建了TWriter对象,然后利用TWriter的WriteDescendant方法将Instance写入流。
var
Writer: TWriter;
begin
Writer := TWriter.Create(Self, 4096);
try
Writer.WriteDescendent(Instance, Ancestor);
finally
Writer.Free;
end;
end;
流TStream
procedure TStream.WriteDescendent(Instance, Ancestor: TComponent); //创建了TWriter对象,然后利用TWriter的WriteDescendant方法将Instance写入流。
var
Writer: TWriter;
begin
Writer := TWriter.Create(Self, 4096);
try
Writer.WriteDescendent(Instance, Ancestor);
finally
Writer.Free;
end;
end;procedure TStream.WriteComponent(Instance: TComponent); //WriteComponent方法只是简单地调用WriteDescendant方法将Instance写入流
begin
WriteDescendent(Instance, nil);
end;