home *** CD-ROM | disk | FTP | other *** search
- unit KGsfStream;
- {*$DEFINE GSFSTREAMCACHE}
-
- interface
- uses SysUtils, Classes, KGsfImport, KGlibImport;
-
- type
- TEnumOle2Open = (Ole2_Read, Ole2_Write);
-
- TMsOleType = (
- MsOleStorageT = 1,
- MsOleStreamT = 2,
- MsOleRootT = 5
- );
- TMsOlePos = guint32;
-
- TMsOleDirInfo = record
- Name: Widestring;
- OleType: TMsOleType;
- Size: TMsOlePos;
- end;
-
- TMsOleDirInfoArray = Array of TMsOleDirInfo;
-
- TStorageList = class(TList)
- protected
- Mode: TEnumOle2Open;
- constructor Create(const aMode: TEnumOle2Open);
- procedure Notify(Ptr: Pointer; Action: TListNotification); override;
- end;
-
- TOle2Storage = class
- private
- FStorages: TStorageList;
- FMode: TEnumOle2Open;
- function GetActiveStorage: pointer;
- published
- xmldummy: TXmlLoader; //This is to load libxml2...
- 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 Mode: TEnumOle2Open read FMode;
- property ActiveStorage: pointer read GetActiveStorage;
- end;
-
- {$IFDEF GSFSTREAMCACHE}
- TOle2Stream = class (TMemoryStream)
- {$ELSE}
- TOle2Stream = class (TStream)
- {$ENDIF}
- protected
- FStorage: TOle2Storage;
- FStream: Pointer;
- public
- constructor Create(const AStorage: TOle2Storage; const StreamName: Widestring);
- destructor Destroy; override;
- {$IFNDEF GSFSTREAMCACHE}
- function Read(var Buffer; Count: Longint): Longint; override;
- function Write(const Buffer; Count: Longint): Longint; override;
- function Seek(Offset: Longint; Origin: Word): Longint; override;
- {$ENDIF}
- end;
-
-
- implementation
- resourcestring
- ErrCantopenStream='Can''t open stream %s';
- ErrCantReadOutStream='Can''t read in an output stream';
- ErrCantWriteInStream='Can''t write in an input stream';
- ErrReadingStream='Error Reading Stream';
-
- { TOle2Storage }
-
- procedure TOle2Storage.CdDown(const Dir: Widestring;
- const CreateIfNeeded: boolean);
- var
- s:string;
- begin
- s:=dir;
- if FMode=Ole2_Write then FStorages.Add(gsf_outfile_new_child(ActiveStorage, PChar(s),true))
- else FStorages.Add(gsf_infile_child_by_name(ActiveStorage, PChar(s)))
- end;
-
- procedure TOle2Storage.CdUp;
- begin
- if FStorages.Count>0 then FStorages.Delete(FStorages.Count-1);
- end;
-
- constructor TOle2Storage.Create(const AFileName: string;
- const aMode: TEnumOle2Open);
- var
- Err: PGError;
- s:string;
- MainFile: pointer;
- begin
- inherited Create;
- Err:=nil;
- FStorages:= TStorageList.Create(aMode);
-
- if aMode= Ole2_Write then
- begin
- MainFile:=gsf_output_stdio_new(PCHAR(AFileName),@Err);
- if Err=nil then
- begin
- FStorages.Add(gsf_outfile_msole_new(MainFile));
- g_object_unref(MainFile);
- end;
- end else
- begin
- MainFile:=gsf_input_stdio_new(PCHAR(AFileName),@Err);
- if Err=nil then
- begin
- FStorages.Add(gsf_infile_msole_new(MainFile, @Err));
- g_object_unref(MainFile);
- end;
- end;
-
- if Err<>nil then
- begin
- s:= Err^.message;
- g_error_free(Err);
- raise Exception.Create(s);
- end;
- FMode:=aMode;
- end;
-
- destructor TOle2Storage.Destroy;
- begin
- FreeAndNil(FStorages);
- inherited;
- end;
-
- function TOle2Storage.GetActiveStorage: pointer;
- begin
- if FStorages.Count>0 then Result:= FStorages[FStorages.Count-1] else Result:=nil;
- end;
-
- procedure TOle2Storage.GetDirectories(var DirInfo: TMsOleDirInfoArray);
- var
- i: integer;
- NewS: pointer;
- begin
- SetLength(DirInfo,0);
- if (FMode<>Ole2_Read) or (FStorages.Count=0) then exit;
- i:=gsf_infile_num_children(ActiveStorage);
- if i<0 then exit;
- SetLength(DirInfo, i);
- for i:=0 to Length(DirInfo)-1 do
- begin
- DirInfo[i].Name:=gsf_infile_name_by_index(ActiveStorage, i);
- DirInfo[i].Size:=gsf_input_size(ActiveStorage);
-
- NewS:=gsf_infile_child_by_index(ActiveStorage, i);
- try
- if gsf_infile_num_children(NewS)>=0 then
- DirInfo[i].OleType:=MsOleStorageT else DirInfo[i].OleType:=MsOleStreamT;
- finally
- g_object_unref(NewS);
- end; //finally
- end;
- end;
-
- { TStorageList }
-
- constructor TStorageList.Create(const aMode: TEnumOle2Open);
- begin
- inherited Create;
- Mode:=aMode;
- end;
-
- procedure TStorageList.Notify(Ptr: Pointer; Action: TListNotification);
- begin
- if Action = lnDeleted then if Ptr<>nil then
- begin
- if (Mode=Ole2_Write) then gsf_output_close(Ptr);
- g_object_unref(Ptr);
- end;
-
- inherited;
- end;
-
- { TOle2Stream }
-
- constructor TOle2Stream.Create(const AStorage: TOle2Storage;
- const StreamName: Widestring);
- var
- s: string;
- begin
- inherited Create;
- s:= StreamName;
- FStorage:= AStorage;
- if FStorage.FMode= Ole2_Write then
- FStream:=gsf_outfile_new_child(FStorage.ActiveStorage, PChar(s), false)
- else
- FStream:=gsf_infile_child_by_name(FStorage.ActiveStorage, PChar(s));
-
- if FStream=nil then raise Exception.CreateFmt(ErrCantOpenStream,[s]);
-
- {$IFDEF GSFSTREAMCACHE}
- if FStorage.FMode=Ole2_Read then
- begin
- Self.Size:= gsf_input_size(FStream);
- if not gsf_input_Read(FStream, Self.Size, Self.Memory) then Raise Exception.Create(ErrReadingStream);
- Self.Position:=0;
- end;
- {$ENDIF}
- end;
-
- destructor TOle2Stream.Destroy;
- begin
- if FStream<>nil then
- begin
- if Fstorage.FMode=Ole2_Write then
- begin
- {$IFDEF GSFSTREAMCACHE}
- Self.Position:=0;
- gsf_output_write(FStream, Self.Size, Self.Memory);
- {$ENDIF}
- gsf_output_close(FStream);
- end;
- g_object_unref(FStream);
- end;
- inherited;
- end;
-
- {$IFNDEF GSFSTREAMCACHE}
- function TOle2Stream.Read(var Buffer; Count: Integer): Longint;
- var
- ok: boolean;
- begin
- if FStorage.FMode= Ole2_Write then raise Exception.Create(ErrCantReadOutStream);
- ok:=gsf_input_read(FStream, Count, @Buffer);
- if not ok then Result:=0 else Result:=Count;
-
- end;
-
- function TOle2Stream.Seek(Offset: Integer; Origin: Word): Longint;
- var
- ok: gboolean;
- Whence: GsfOff_t;
- begin
- case Origin of
- soFromBeginning: Whence:=GSF_SEEK_SET;
- soFromCurrent : Whence:=GSF_SEEK_CUR;
- soFromEnd : Whence:=GSF_SEEK_END;
- else begin; Result:=-1; exit; end;
- end; //case
-
- if FStorage.FMode= Ole2_Write then
- begin
- ok:=gsf_output_seek(FStream, Offset, Whence);
- if ok then Result:=-1 else Result:=gsf_output_tell(FStream);
- end else
- begin
- ok:=gsf_input_seek(FStream, Offset, Whence);
- if ok then Result:=-1 else Result:=gsf_input_tell(FStream);
- end;
- end;
-
- function TOle2Stream.Write(const Buffer; Count: Integer): Longint;
- var
- ok: boolean;
- begin
- if FStorage.FMode= Ole2_Read then raise Exception.Create(ErrCantWriteInStream);
- ok:=gsf_output_write(FStream, Count, @Buffer);
- if not ok then Result:=0 else Result:=Count;
- end;
- {$ENDIF}
-
- initialization
- gsf_init;
- finalization
- gsf_shutdown;
- end.
-