SrmUnit.~pa
资源名称:srmsrc.zip [点击查看]
上传用户:tj00001
上传日期:2007-01-07
资源大小:672k
文件大小:12k
源码类别:
行业应用
开发平台:
Delphi
- //---------------------------------------------------------------------------
- //(R)CopyRight KivenSoft International ,inc 1999
- //单元名称:数据库单元
- //程序名称:电子书库
- //作 者:李会文
- //开始时间:1998.07.28
- //最后修改:1999.07.22
- //备注:此单元定义了SRM文件的读写接口
- //---------------------------------------------------------------------------
- unit SrmUnit;
- interface
- uses
- Windows,SysUtils,Classes, SrmConst;
- type
- PCharArray=^TCharArray;
- TCharArray=array[0..0] of char;
- PDwordArray=^TDwordArray;
- TDwordArray=array[0..0] of DWORD;
- PIntArray=^TIntArray;
- TIntArray=array[0..0] of integer;
- PTreeData=^TTreeData;
- TTreeData=record //索引信息
- Pos: longint;
- DataType: longint;
- end;
- PTdArray=^TTdArray;
- TTdArray=array[0..0] of TTreeData;
- PFileHead=^TFileHead;
- TFileHead=record
- OpenFlag :Longint; //数据库打开标志
- LastViewPos :longint; //关闭时的位置
- IndexPos :longint; //索引位置
- EditDate :TDateTime; //最后修改日期
- Key :DWORD; //密钥
- Password :array[0..11] of char; //口令
- Author :array[0..15] of char; //作者
- BuildDate :TDateTime; //建库日期
- DataType :longint; //数据库格式
- DataFlag :array[0..7] of char; //数据库标志
- Version :longint; //数据库版本
- BookMerg :array[0..9] of longint; //10个书签
- Keep :longint; //保留字段
- end;
- //DataType 0:Index 1:Normal Dir 2:Notmal TXT 3:Normal HTML
- PIndexHead=^TIndexHead;
- TIndexHead=record
- DataType :longint; //段类型
- Key :DWORD; //密钥
- Count :longint; //标题数量
- Size :longint; //标题长度
- Keep :longint; //保留字段
- end;
- PDataHead=^TDataHead;
- TDataHead=record
- DataType :longint; //段类型
- Author :array[0..15] of char; //作者
- PubDate :TDateTime; //收录日期
- Key :DWORD; //密钥
- Num :longint; //附件数量
- SearchKey :array[0..51] of char; //关键词
- Password :array[0..11] of char; //口令
- Keep :longint; //保留字段
- end;
- //------------------------------------------------------------------------
- TSrmObject=class
- private
- FChangeFlag :boolean; //在文件后有增加新信息的变量
- FDbChanged :boolean; //数据库属性有变动
- FIndexChanged :boolean; //索引有变动
- FItemHeadChanged :boolean; //标题头有变动
- FItemDataChanged :boolean; //标题内容有变动
- FFileHead :TFileHead;
- FIndexHead :TIndexHead;
- FDataHead :TDataHead;
- FFileHandle :integer; //文件句柄
- FFileName :string;
- FActivePos :longint; //当前读出内容的位置
- procedure Encypher(Cypher:DWORD;var Buf;Count:integer);
- procedure Decypher(Cypher:DWORD;var Buf;Count:integer);
- procedure CreateSrmFile; //建立一个空数据库
- procedure SetDbChanged(Value:boolean);
- procedure SetIndexChanged(Value:boolean);
- procedure SetItemHeadChanged(Value:boolean);
- procedure SetItemDataChanged(Value:boolean);
- public
- property FileName:string read FFileName;
- property FileHead:TFileHead read FFileHead write FFileHead;
- property IndexHead:TIndexHead read FIndexHead write FIndexHead;
- property DataHead:TDataHead read FDataHead write FDataHead;
- property ActivePos:longint read FActivePos write FActivePos;
- property DbChanged:boolean read FDbChanged write SetDbChanged;
- property IndexChanged:boolean read FIndexChanged write SetIndexChanged;
- property ItemHeadChanged:boolean read FItemHeadChanged write SetItemHeadChanged;
- property ItemDataChanged:boolean read FItemDataChanged write SetItemDataChanged;
- constructor Create(Fn:string;Mode:Word);
- destructor Destroy;override;
- procedure Free;
- procedure SaveSrmFile; //不关闭文件情况下保存文件
- procedure LoadIndex(Msh,Msd:TMemoryStream); //读索引
- procedure SaveIndex(Msh,Msd:TMemoryStream);//写索引
- class function IsSrmFile(var Fn:string):boolean;//判断是否是SRM格式数据库文件
- procedure ReadItemHead(Ps:longint); //读数据段头
- procedure ReadItemData(DataStream:TMemoryStream); //读数据段内容
- procedure EditItemHead(Ps:longint); //修改数据头
- function AddItemHead:longint; //写数据段头
- procedure AddItemData(DataStream:TMemoryStream); //写数据段内容
- function GetItemPassword(Ps:longint):string; //得某标题口令
- end;
- //------------------------------------------------------------------------
- implementation
- //------------------------------------------------------------------------
- procedure TSrmObject.Encypher(Cypher:DWORD;var Buf;Count:integer);
- var
- i:integer;
- begin
- Cypher:=not Cypher;
- Dec(Count);
- for i:=0 to Count do
- TDwordArray(Buf)[i]:=TDwordArray(Buf)[i] xor Cypher;
- end;
- procedure TSrmObject.Decypher(Cypher:DWORD;var Buf;Count:integer);
- var
- i:integer;
- begin
- Cypher:=not Cypher;
- Dec(Count);
- for i:=0 to Count do
- TDwordArray(Buf)[i]:=TDwordArray(Buf)[i] xor Cypher;
- end;
- //------------------------------------------------------------------------
- procedure TSrmObject.CreateSrmFile; //建立一个空数据库
- var
- i:integer;
- begin
- FFileHandle:=FileCreate(FFileName);
- if FFileHandle=-1 then raise Exception.Create(csCanNotCreate);
- //添充缺省信息头
- with FFileHead do
- begin
- OpenFlag:=0;
- LastViewPos:=0;
- IndexPos:=sizeof(TFileHead);
- EditDate:=Now;
- Key:=GetTickCount;
- Password[0]:=#0;
- Author[0]:=#0;
- BuildDate:=EditDate;
- DataType:=0;
- Version:=3;
- Keep:=0;
- DataFlag[0]:='K';
- DataFlag[1]:='i';
- DataFlag[2]:='v';
- DataFlag[3]:='e';
- DataFlag[4]:='n';
- for i:=0 to 9 do BookMerg[i]:=-1;
- end;
- //添充缺省索引
- with FIndexHead do
- begin
- DataType:=0;
- Key:=GetTickCount;
- Count:=0;
- Size:=0;
- Keep:=0;
- end;
- //加密写入文件后解密
- with FFileHead do
- begin
- Encypher(Key,Author,4);
- Encypher(Key,Password,3);
- FileWrite(FFileHandle,FFileHead,sizeof(TFileHead));
- FileWrite(FFileHandle,FIndexHead,sizeof(TIndexHead));
- Decypher(Key,Author,4);
- Decypher(Key,Password,3);
- end;
- end;
- constructor TSrmObject.Create(Fn:string;Mode:Word);
- begin
- FFileName:=Fn;
- FChangeFlag:=false;
- FDbChanged:=false;
- FIndexChanged:=false;
- FItemHeadChanged:=false;
- FItemDataChanged:=false;
- FDataHead.Keep:=0;
- //打开文件时读文件头,否则建新文件
- if Mode=fmOpenReadWrite then
- begin
- FFileHandle:=FileOpen(FFileName,fmOpenReadWrite);
- FileRead(FFileHandle,FFileHead,sizeof(TFileHead));
- with FFileHead do
- begin
- Decypher(Key,Password,3);
- Decypher(Key,Author,4);
- end;
- end
- else if Mode=fmCreate then
- begin
- CreateSrmFile;
- end;
- end;
- destructor TSrmObject.Destroy;
- begin
- if FFileHandle<>-1 then
- begin
- FileClose(FFileHandle); //关闭文件
- FFileHandle:=-1;
- end;
- inherited;
- end;
- procedure TSrmObject.Free;
- begin
- if Assigned(self) then Destroy;
- end;
- procedure TSrmObject.SaveSrmFile;
- begin
- //写入更新后的文件头
- with FFileHead do
- begin
- FileSeek(FFileHandle,0,0);
- EditDate:=Now;
- Key:=GetTickCount;
- Encypher(Key,Password,3);
- Encypher(Key,Author,4);
- FileWrite(FFileHandle,FFileHead,sizeof(TFileHead));
- Decypher(Key,Password,3);
- Decypher(Key,Author,4);
- end;
- end;
- class function TSrmObject.IsSrmFile(var Fn:string):boolean;
- var
- Fh: TFileHead;
- Fs: TFileStream;
- begin
- Result:=false;
- Fs:=TFileStream.Create(Fn,fmOpenRead);
- //根据文件长度判断
- with Fs do
- begin
- if (Size<(sizeof(TFileHead)+sizeof(TIndexHead))) then
- begin
- Free;
- Result:=false;
- Exit;
- end;
- Read(Fh,sizeof(TFileHead));
- Free;
- end;
- //根据文件标志判断
- with Fh do
- begin
- if ( (DataFlag[0]='K') and (DataFlag[1]='i') and
- (DataFlag[2]='v') and (DataFlag[3]='e') and
- (DataFlag[4]='n') ) then
- Result:=true;
- end;
- end;
- procedure TSrmObject.LoadIndex(Msh,Msd:TMemoryStream);
- begin
- //读出索引头
- FileSeek(FFileHandle,FFileHead.IndexPos,0);
- FileRead(FFileHandle,FIndexHead,sizeof(TIndexHead));
- //处理索引长度为0的状况,否则读出具体索引
- if (FIndexHead.Size=0) then
- begin
- Msh.SetSize(0);
- Msd.SetSize(0);
- end
- else
- begin
- Msh.SetSize(FIndexHead.Size);
- Msd.SetSize(FIndexHead.Count*sizeof(longint)*2);
- FileRead(FFileHandle,Msh.Memory^,Msh.Size);
- FileRead(FFileHandle,Msd.Memory^,Msd.Size);
- Decypher(FIndexHead.Key,Msh.Memory^,Msh.Size div 4);
- end;
- end;
- procedure TSrmObject.SaveIndex(Msh,Msd:TMemoryStream);
- begin
- if FChangeFlag then //增加过新内容时
- FFileHead.IndexPos:=FileSeek(FFileHandle,0,2)
- else //无新增内容
- FileSeek(FFileHandle,FFileHead.IndexPos,0);
- //设置数据头
- with FIndexHead do
- begin
- Key:=GetTickCount;
- Size:=Msh.Size;
- Count:=Msd.Size div (sizeof(longint)*2);
- end;
- //加密标题内容
- Encypher(FIndexHead.Key,Msh.Memory^,Msh.Size div 4);
- //写入索引
- FileWrite(FFileHandle,FIndexHead,sizeof(TIndexHead));
- FileWrite(FFileHandle,Msh.Memory^,Msh.Size);
- FileWrite(FFileHandle,Msd.Memory^,Msd.Size);
- end;
- procedure TSrmObject.ReadItemHead(Ps:longint);
- begin
- FActivePos:=Ps; //保存当前数据位置
- //读出并解密
- with FDataHead do
- begin
- FileSeek(FFileHandle,Ps,0);
- FileRead(FFileHandle,FDataHead,sizeof(TDataHead));
- Decypher(Key,SearchKey,13);
- Decypher(Key,Author,4);
- Decypher(Key,Password,3);
- end;
- end;
- procedure TSrmObject.ReadItemData(DataStream:TMemoryStream);
- var
- size:longint;
- begin
- //读出具体内容
- FileRead(FFileHandle,size,sizeof(longint));
- DataStream.SetSize(size);
- FileRead(FFileHandle,DataStream.Memory^,size);
- Decypher(FDataHead.Key,DataStream.Memory^,size div 4);
- end;
- procedure TSrmObject.EditItemHead(Ps:longint);
- begin
- //修改数据头
- FileSeek(FFileHandle,Ps,0);
- with FDataHead do
- begin
- Encypher(Key,SearchKey,13);
- Encypher(Key,Author,4);
- Encypher(Key,Password,3);
- FileWrite(FFileHandle,FDataHead,sizeof(TDataHead));
- Decypher(Key,SearchKey,13);
- Decypher(Key,Author,4);
- Decypher(Key,Password,3);
- end;
- end;
- function TSrmObject.AddItemHead:longint;
- begin
- //新内容增加时移到文件尾添加
- FChangeFlag:=true;
- with FDataHead do
- begin
- Result:=FileSeek(FFileHandle,0,2);
- Key:=GetTickCount;
- PubDate:=Now;
- Encypher(Key,SearchKey,13);
- Encypher(Key,Author,4);
- Encypher(Key,Password,3);
- FileWrite(FFileHandle,FDataHead,sizeof(TDataHead));
- Decypher(Key,SearchKey,13);
- Decypher(Key,Author,4);
- Decypher(Key,Password,3);
- end;
- end;
- procedure TSrmObject.AddItemData(DataStream:TMemoryStream);
- var
- size:longint;
- begin
- size:=DataStream.Size;
- FileWrite(FFileHandle,size,sizeof(longint));
- Encypher(FDataHead.Key,DataStream.Memory^,size div 4);
- FileWrite(FFileHandle,DataStream.Memory^,size);
- end;
- function TSrmObject.GetItemPassword(Ps:longint):string; //得某标题口令
- var
- Dh:TDataHead;
- begin
- //读出并解密
- with Dh do
- begin
- FileSeek(FFileHandle,Ps,0);
- FileRead(FFileHandle,Dh,sizeof(TDataHead));
- Decypher(Key,Password,3);
- end;
- result:=string(Dh.Password);
- end;
- procedure TSrmObject.SetDbChanged(Value:boolean);
- begin
- FDbChanged:=Value;
- end;
- procedure TSrmObject.SetIndexChanged(Value:boolean);
- begin
- FIndexChanged:=Value;
- if Value then FDbChanged:=Value;
- end;
- procedure TSrmObject.SetItemHeadChanged(Value:boolean);
- begin
- FItemHeadChanged:=Value;
- if Value then
- begin
- FIndexChanged:=Value;
- FDbChanged:=Value;
- end;
- end;
- procedure TSrmObject.SetItemDataChanged(Value:boolean);
- begin
- FItemDataChanged:=Value;
- if Value then
- begin
- FIndexChanged:=Value;
- FDbChanged:=Value;
- end;
- end;
- end.