begin
if CompareText(Name, FPropName) = 0 then
begin
if ReadValue <> vaBinary then
begin
Dec(FBufPos);
SkipValue;
FCanHandleExcepts := True;
PropValueError;
end;
Stream := TMemoryStream.Create;
try
Read(Count, SizeOf(Count));
Stream.SetSize(Count);
Read(Stream.Memory^, Count);
FCanHandleExcepts := True;
ReadData(Stream);
finally
Stream.Free;
end;
FPropName := '';
end;
end;
在两个方法都将Name参数值与当前的属性名比较,如果相同则进行读操作。在DefineBinaryproperty中,创建了一个内存流。先将数据读到内存流中然后调用ReadData读取数据。
3. FlushBuffer的实现
FlushBuffer方法用于清除Reader对象的内部缓冲区中的内容,保持Reader对象和流在位置(Position)上的同步,其实现如下:
procedure TReader.FlushBuffer;
begin
FStream.Position := FStream.Position - (FBufEnd - FBufPos);
FBufPos := 0;
FBufEnd := 0;
end;
4. ReadListBegin、ReadListEnd和EndOfList方法
这三个方法都是用于从Reader对象的流中读取一连串的项目,并且这些项目都由WriteListBegin写入的标志标定开始和WriteListEnd写入标志,标定结束,在读循环中用EndOfList进行判断。它们是在Reader对象读取流中数据时经常用于的。它们的实现如下:
procedure TReader.ReadListBegin;
begin
CheckValue(vaList);
end;
procedure TReader.ReadListEnd;
begin
CheckValue(vaNull);
end;
function TReader.EndOfList: Boolean;
begin
Result := ReadValue = vaNull;
Dec(FBufPos);
end;
项目表开始标志是VaList,项目表结束标志是VaNull,VaList和VaNull都是枚举类型TValueType定义的常量。
它们实现中调用的CheckValue是TReader的私有方法,其实现如下:
procedure TReader.CheckValue(Value: TValueType);
begin
if ReadValue <> Value then
begin
Dec(FBufPos);
SkipValue;
PropValueError;
end;
end;
CheckValue方法的功能是检测紧接着要读的值是否是Value指定的类型。如果不是则跳过该项目并触发一个SInvalidPropertyValue错误。
EndOfList函数只是简单地判断下一字节是否是VaNull将判断结果返回,并将字节移回原来位置。
5. 简单数据类型读方法的实现
简单数据类型指的是布尔型、字符型、整型、字符串型、浮点型、集合类型和标识符。将它们放在一起介绍是因为它们的实现方法类似。
因为它们的实现都用到了ReadValue方法,因此先来介绍ReadValue方法的实现:
function TReader.ReadValue: TValueType;
begin
Read(Result, SizeOf(Result));
end;
该方法调用私有方法Read,从Reader对象流中读一个字节,并移动位置指针。
ReadValue方法专门从流中读取值的类型的,所有的数据读写方法中在读取数据前都要调用ReadValue方法判断是否是所要读的数据。如果是,则调用Read方法读取数据;否则触发一个异常事件,下面看Integer类型的读方法:
function TReader.ReadInteger: Longint;
var
S: Shortint;
I: Smallint;
begin
case ReadValue of
vaInt8:
begin
Read(S, SizeOf(Shortint));
上一页 [1] [2] [3] [4] [5] [6] [7] [8] 下一页
|