📄 kole2stream.pas
字号:
unit KOLE2Stream;
{$IFDEF LINUX}{$INCLUDE ../FLXCOMPILER.INC}{$ELSE}{$INCLUDE ..\FLXCOMPILER.INC}{$ENDIF}
interface
uses SysUtils, Classes, KOLE2Import;
type
TEnumOle2Open = (Ole2_Read, Ole2_Write);
TMsOleDirInfo = record
Name: Widestring;
OleType: TMsOleType;
Size: TMsOlePos;
end;
TMsOleDirInfoArray = Array of TMsOleDirInfo;
TOle2Storage = class
private
Ffs: PMsOle;
FMode: TEnumOle2Open;
FPath: Widestring;
public
constructor Create(const AFileName: string; const aMode: TEnumOle2Open);
destructor Destroy;override;
procedure GetDirectories(var DirInfo: TMsOleDirInfoArray);
procedure CdUp;
procedure CdDown(const Dir: Widestring; const CreateIfNeeded: boolean);
property Fs: PMsOle read Ffs;
property Mode: TEnumOle2Open read FMode;
property Path: Widestring read FPath write FPath;
end;
TOle2Stream = class (TStream)
protected
FStorage: TOle2Storage;
FStream: PMsOleStream;
public
constructor Create(const AStorage: TOle2Storage; const StreamName: Widestring);
destructor Destroy; override;
function Read(var Buffer; Count: Longint): Longint; override;
function Write(const Buffer; Count: Longint): Longint; override;
function Seek(Offset: Longint; Origin: Word): Longint; override;
end;
procedure OLE2Check(const Err: TMsOleErr);
implementation
resourcestring
ErrLibOle2='Error in OLE file: ERR_%s';
Txt_OLE_ERR_OK='OK';
Txt_OLE_ERR_EXIST='EXIST';
Txt_OLE_ERR_INVALID='INVALID';
Txt_OLE_ERR_FORMAT='FORMAT';
Txt_OLE_ERR_PERM='PERMISSIONS';
Txt_OLE_ERR_MEM,='MEMORY';
Txt_OLE_ERR_SPACE='SPACE';
Txt_OLE_ERR_NOTEMPTY)='NOT EMPTY';
Txt_OLE_ERR_BADARG='BAD ARGUMENT';
TxtUndefined='UNDEFINED';
const
ArrayErrTxt: array[TMsOleErr] of string= (
Txt_OLE_ERR_OK,
Txt_OLE_ERR_EXIST,
Txt_OLE_ERR_INVALID,
Txt_OLE_ERR_FORMAT,
Txt_OLE_ERR_PERM,
Txt_OLE_ERR_MEM,
Txt_OLE_ERR_SPACE,
Txt_OLE_ERR_NOTEMPTY,
Txt_OLE_ERR_BADARG
);
{ TOle2Storage }
procedure TOle2Storage.CdDown(const Dir: Widestring; const CreateIfNeeded: boolean);
begin
//CreateIfNeeded not used with libole2
if (Length(Path)>0) and (Path[Length(Path)]=PathDelim) then Path:=Path+Dir
else Path:=Path+PathDelim+Dir;
end;
procedure TOle2Storage.CdUp;
begin
Path:=copy(Path, 1, LastDelimiter(PathDelim,Path)-1);
if Path='' then Path:=PathDelim;
end;
constructor TOle2Storage.Create(const AFileName: string; const aMode: TEnumOle2Open);
begin
inherited Create;
if aMode= Ole2_Write then OLE2Check(ms_ole_create(@Ffs, PCHAR(AFileName)))
else
if aMode= Ole2_Read then OLE2Check(ms_ole_open(@Ffs, PCHAR(AFileName)));
Path:=PathDelim;
FMode:=aMode;
end;
destructor TOle2Storage.Destroy;
begin
if Ffs<>nil then ms_ole_destroy(@Ffs);
inherited;
end;
procedure TOle2Storage.GetDirectories(var DirInfo: TMsOleDirInfoArray);
var
DirStats: TMsOleStat;
nPath: string;
Names: PPChar;
NamesArray: PPointerArray;
i: integer;
begin
nPath:=Path;
OLE2Check(ms_ole_directory(@Names, Ffs, PCHAR(nPath)));
NamesArray:=PPointerArray(Names);
try
SetLength(DirInfo,0);
while NamesArray[Length(DirInfo)]<>nil do
begin
SetLength(DirInfo,Length(DirInfo)+1);
DirInfo[Length(DirInfo)-1].Name:=PChar(NamesArray[Length(DirInfo)-1]);
OLE2Check(ms_ole_stat(@(DirStats), Ffs, PCHAR(nPath), NamesArray[Length(DirInfo)-1]));
DirInfo[Length(DirInfo)-1].OleType:=DirStats.OleType;
DirInfo[Length(DirInfo)-1].Size:=DirStats.Size;
end;
finally
i:=0;
while NamesArray[i]<>nil do
begin
FreeMemory(NamesArray[i]);
inc(i);
end;
FreeMemory(Names);
end; //finally
end;
{ TOle2Stream }
constructor TOle2Stream.Create(const AStorage: TOle2Storage; const StreamName: Widestring);
var
m:Char;
nPath, nStreamName: string;
begin
inherited Create;
FStorage:= AStorage;
nPath:=FStorage.Path;nStreamName:=StreamName;
if Fstorage.Mode=Ole2_Read then m:= 'r' else m:='w';
OLE2Check(ms_ole_stream_open(@FStream, FStorage.Fs, PCHAR(nPath), PCHAR(nStreamName), m));
end;
destructor TOle2Stream.Destroy;
begin
if FStream<> nil then ms_ole_stream_close(@FStream);
inherited;
end;
function TOle2Stream.Read(var Buffer; Count: Longint): Longint;
begin
if FStream=nil then begin; Result:=0; exit; end;
if FStream.read_copy( FStream, @Buffer, Count)<>0 then //Here 0 is NIL = error
Result := Count else Result := 0;
end;
function TOle2Stream.Write(const Buffer; Count: Longint): Longint;
begin
if FStream=nil then begin; Result:=0; exit; end;
if FStream.write( FStream, @Buffer, Count)<>0 then
Result := Count else Result := 0;
end;
function TOle2Stream.Seek(Offset: Longint; Origin: Word): Longint;
var
oleType: TMsOleSeek;
begin
if FStream=nil then begin; Result:=-1; exit; end;
case Origin of
soFromBeginning: oleType:=MsOleSeekSet;
soFromCurrent : oleType:=MsOleSeekCur;
soFromEnd : oleType:=MsOleSeekEnd;
else begin; Result:=-1; exit; end;
end; //case
Result:= FStream.lseek( FStream, Offset, oleType);
end;
procedure OLE2Check(const Err: TMsOleErr);
begin
case Err of
MS_OLE_ERR_OK: exit;
MS_OLE_ERR_EXIST,
MS_OLE_ERR_INVALID,
MS_OLE_ERR_FORMAT,
MS_OLE_ERR_PERM,
MS_OLE_ERR_MEM,
MS_OLE_ERR_SPACE,
MS_OLE_ERR_NOTEMPTY,
MS_OLE_ERR_BADARG: raise Exception.CreateFmt(ErrLibOle2, [ArrayErrTxt[Err]]);
else raise Exception.CreateFmt(ErrLibOle2, [TxtUndefined]);
end; //case;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -