Welcome

首页 / 软件开发 / Delphi / 第二十章-开发Delphi对象式数据管理功能(四)(4)

第二十章-开发Delphi对象式数据管理功能(四)(4)2007-05-075. 简单数据类型读方法的实现

简单数据类型指的是布尔型、字符型、整型、字符串型、浮点型、集合类型和标识符。将它们放在一起介绍是因为它们的实现方法类似。

因为它们的实现都用到了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));

Result := S;

end;

vaInt16:

begin

Read(I, SizeOf(I));

Result := I;

end;

vaInt32:

Read(Result, SizeOf(Result));

else

PropValueError;

end;

end;

因为Delphi 2.0中,整型可分8位、16位和32位,因此读取整型数据时分别作了判断。

布尔类型的数据是直接放在值类型标志上,如果类型为VaTrue,则值为True;如果类型为VaFalse,则值为False。

function TReader.ReadBoolean: Boolean;

begin

Result := ReadValue = vaTrue;

end;

ReadString方法也利用ReadValue方法判断是字符串还是长字符串。

function TReader.ReadString: string;

var

L: Integer;

begin

L := 0;

case ReadValue of

vaString:

Read(L, SizeOf(Byte));

vaLString:

Read(L, SizeOf(Integer));

else

PropValueError;

end;

SetString(Result, PChar(nil), L);

Read(Pointer(Result)^, L);

end;

如果VaString类型紧接着一个字节存有字符串的长度;如果是VaLString类,则紧接着两个字节存放字符串长度,然后根据字符串长度用SetString过程给分配空间,用Read方法读出数据。

ReadFloat方法允许将整型值转换为浮点型。

function TReader.ReadFloat: Extended;

begin

if ReadValue = vaExtended then Read(Result, SizeOf(Result)) else

begin

Dec(FBufPos);

Result := ReadInteger;

end;

end;

字符类型数据设有直接的标志,它是根据VaString后面放一个序值为1的字节来判断的。

function TReader.ReadChar: Char;

begin

CheckValue(vaString);

Read(Result, 1);

if Ord(Result) <> 1 then

begin

Dec(FBufPos);

ReadStr;

PropValueError;

end;

Read(Result, 1);

end;

出于读取DFM文件需要,Filer对象支持读取标识符。

function TReader.ReadIdent: string;

var

L: Byte;

begin

case ReadValue of

vaIdent:

begin

Read(L, SizeOf(Byte));

SetString(Result, PChar(nil), L);

Read(Result[1], L);

end;

vaFalse:

Result := "False";

vaTrue:

Result := "True";

vaNil:

Result := "nil";

else

PropValueError;

end;

end;

一般说来,各种复杂的数据结构都是由这些简单数据组成;定义了这些方法等于给读各种类型的数据提供了元操作,使用很方便。例如,读取字符串类型的数据时,如果采用传流方法还要判断字符串的长度,使用ReadString方法就不同了。但应该特别注意的是这些类型数据的存储格式是由Delphi设计的与简单数据类型有明显的不同。因此,存入数据时应当使用Writer对象相应的方法,而且在读数据前要用NextValue方法进行判断,否则会触发异常事件。