home *** CD-ROM | disk | FTP | other *** search
/ Chip 2003 January / Chip_2003-01_cd1.bin / zkuste / delphi / kolekce / d567 / FLEXCEL.ZIP / XLSAdapter / KGsfStream.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  2002-09-26  |  6.9 KB  |  280 lines

  1. unit KGsfStream;
  2. {*$DEFINE GSFSTREAMCACHE}
  3.  
  4. interface
  5. uses SysUtils, Classes, KGsfImport, KGlibImport;
  6.  
  7. type
  8.   TEnumOle2Open = (Ole2_Read, Ole2_Write);
  9.  
  10.   TMsOleType = (
  11.     MsOleStorageT = 1,
  12.     MsOleStreamT  = 2,
  13.     MsOleRootT    = 5
  14.   );
  15.   TMsOlePos = guint32;
  16.  
  17.   TMsOleDirInfo = record
  18.     Name: Widestring;
  19.     OleType: TMsOleType;
  20.     Size: TMsOlePos;
  21.   end;
  22.  
  23.   TMsOleDirInfoArray = Array of TMsOleDirInfo;
  24.  
  25.   TStorageList = class(TList)
  26.   protected
  27.     Mode: TEnumOle2Open;
  28.     constructor Create(const aMode: TEnumOle2Open);
  29.     procedure Notify(Ptr: Pointer; Action: TListNotification); override;
  30.   end;
  31.  
  32.   TOle2Storage = class
  33.   private
  34.     FStorages: TStorageList;
  35.     FMode: TEnumOle2Open;
  36.     function GetActiveStorage: pointer;
  37.   published
  38.     xmldummy: TXmlLoader; //This is to load libxml2...
  39.   public
  40.     constructor Create(const AFileName: string; const aMode: TEnumOle2Open);
  41.     destructor Destroy;override;
  42.  
  43.     procedure GetDirectories(var DirInfo: TMsOleDirInfoArray);
  44.     procedure CdUp;
  45.     procedure CdDown(const Dir: Widestring; const CreateIfNeeded: boolean);
  46.  
  47.     property Mode: TEnumOle2Open read FMode;
  48.     property ActiveStorage: pointer read GetActiveStorage;
  49.   end;
  50.  
  51. {$IFDEF GSFSTREAMCACHE}
  52.   TOle2Stream = class (TMemoryStream)
  53. {$ELSE}
  54.   TOle2Stream = class (TStream)
  55. {$ENDIF}
  56.   protected
  57.     FStorage: TOle2Storage;
  58.     FStream: Pointer;
  59.   public
  60.     constructor Create(const AStorage: TOle2Storage; const StreamName: Widestring);
  61.     destructor Destroy; override;
  62. {$IFNDEF GSFSTREAMCACHE}
  63.     function Read(var Buffer; Count: Longint): Longint; override;
  64.     function Write(const Buffer; Count: Longint): Longint; override;
  65.     function Seek(Offset: Longint; Origin: Word): Longint; override;
  66. {$ENDIF}
  67.   end;
  68.  
  69.  
  70. implementation
  71. resourcestring
  72.   ErrCantopenStream='Can''t open stream %s';
  73.   ErrCantReadOutStream='Can''t read in an output stream';
  74.   ErrCantWriteInStream='Can''t write in an input stream';
  75.   ErrReadingStream='Error Reading Stream';
  76.  
  77. { TOle2Storage }
  78.  
  79. procedure TOle2Storage.CdDown(const Dir: Widestring;
  80.   const CreateIfNeeded: boolean);
  81. var
  82.   s:string;
  83. begin
  84.   s:=dir;
  85.   if FMode=Ole2_Write then FStorages.Add(gsf_outfile_new_child(ActiveStorage, PChar(s),true))
  86.   else FStorages.Add(gsf_infile_child_by_name(ActiveStorage, PChar(s)))
  87. end;
  88.  
  89. procedure TOle2Storage.CdUp;
  90. begin
  91.   if FStorages.Count>0 then FStorages.Delete(FStorages.Count-1);
  92. end;
  93.  
  94. constructor TOle2Storage.Create(const AFileName: string;
  95.   const aMode: TEnumOle2Open);
  96. var
  97.   Err: PGError;
  98.   s:string;
  99.   MainFile: pointer;
  100. begin
  101.   inherited Create;
  102.   Err:=nil;
  103.   FStorages:= TStorageList.Create(aMode);
  104.  
  105.   if aMode= Ole2_Write then
  106.   begin
  107.     MainFile:=gsf_output_stdio_new(PCHAR(AFileName),@Err);
  108.     if Err=nil then
  109.     begin
  110.       FStorages.Add(gsf_outfile_msole_new(MainFile));
  111.       g_object_unref(MainFile);
  112.     end;
  113.   end else
  114.   begin
  115.     MainFile:=gsf_input_stdio_new(PCHAR(AFileName),@Err);
  116.     if Err=nil then
  117.     begin
  118.       FStorages.Add(gsf_infile_msole_new(MainFile, @Err));
  119.       g_object_unref(MainFile);
  120.     end;
  121.   end;
  122.  
  123.   if Err<>nil then
  124.   begin
  125.     s:= Err^.message;
  126.     g_error_free(Err);
  127.     raise Exception.Create(s);
  128.   end;
  129.   FMode:=aMode;
  130. end;
  131.  
  132. destructor TOle2Storage.Destroy;
  133. begin
  134.   FreeAndNil(FStorages);
  135.   inherited;
  136. end;
  137.  
  138. function TOle2Storage.GetActiveStorage: pointer;
  139. begin
  140.   if FStorages.Count>0 then Result:= FStorages[FStorages.Count-1] else Result:=nil;
  141. end;
  142.  
  143. procedure TOle2Storage.GetDirectories(var DirInfo: TMsOleDirInfoArray);
  144. var
  145.   i: integer;
  146.   NewS: pointer;
  147. begin
  148.   SetLength(DirInfo,0);
  149.   if (FMode<>Ole2_Read) or (FStorages.Count=0) then exit;
  150.   i:=gsf_infile_num_children(ActiveStorage);
  151.   if i<0 then exit;
  152.   SetLength(DirInfo, i);
  153.   for i:=0 to Length(DirInfo)-1 do
  154.   begin
  155.     DirInfo[i].Name:=gsf_infile_name_by_index(ActiveStorage, i);
  156.     DirInfo[i].Size:=gsf_input_size(ActiveStorage);
  157.  
  158.     NewS:=gsf_infile_child_by_index(ActiveStorage, i);
  159.     try
  160.       if gsf_infile_num_children(NewS)>=0 then
  161.         DirInfo[i].OleType:=MsOleStorageT else DirInfo[i].OleType:=MsOleStreamT;
  162.     finally
  163.       g_object_unref(NewS);
  164.     end; //finally
  165.   end;
  166. end;
  167.  
  168. { TStorageList }
  169.  
  170. constructor TStorageList.Create(const aMode: TEnumOle2Open);
  171. begin
  172.   inherited Create;
  173.   Mode:=aMode;
  174. end;
  175.  
  176. procedure TStorageList.Notify(Ptr: Pointer; Action: TListNotification);
  177. begin
  178.   if Action = lnDeleted then if Ptr<>nil then
  179.   begin
  180.     if (Mode=Ole2_Write) then gsf_output_close(Ptr);
  181.     g_object_unref(Ptr);
  182.   end;
  183.  
  184.   inherited;
  185. end;
  186.  
  187. { TOle2Stream }
  188.  
  189. constructor TOle2Stream.Create(const AStorage: TOle2Storage;
  190.   const StreamName: Widestring);
  191. var
  192.   s: string;
  193. begin
  194.   inherited Create;
  195.   s:= StreamName;
  196.   FStorage:= AStorage;
  197.   if FStorage.FMode= Ole2_Write then
  198.     FStream:=gsf_outfile_new_child(FStorage.ActiveStorage, PChar(s), false)
  199.   else
  200.     FStream:=gsf_infile_child_by_name(FStorage.ActiveStorage, PChar(s));
  201.  
  202.   if FStream=nil then raise Exception.CreateFmt(ErrCantOpenStream,[s]);
  203.  
  204. {$IFDEF GSFSTREAMCACHE}
  205.   if FStorage.FMode=Ole2_Read then
  206.   begin
  207.     Self.Size:= gsf_input_size(FStream);
  208.     if not gsf_input_Read(FStream, Self.Size, Self.Memory) then Raise Exception.Create(ErrReadingStream);
  209.     Self.Position:=0;
  210.   end;
  211. {$ENDIF}
  212. end;
  213.  
  214. destructor TOle2Stream.Destroy;
  215. begin
  216.   if FStream<>nil then
  217.   begin
  218.     if Fstorage.FMode=Ole2_Write then
  219.     begin
  220. {$IFDEF GSFSTREAMCACHE}
  221.       Self.Position:=0;
  222.       gsf_output_write(FStream, Self.Size, Self.Memory);
  223. {$ENDIF}
  224.       gsf_output_close(FStream);
  225.     end;
  226.     g_object_unref(FStream);
  227.   end;
  228.   inherited;
  229. end;
  230.  
  231. {$IFNDEF GSFSTREAMCACHE}
  232. function TOle2Stream.Read(var Buffer; Count: Integer): Longint;
  233. var
  234.   ok: boolean;
  235. begin
  236.   if FStorage.FMode= Ole2_Write then raise Exception.Create(ErrCantReadOutStream);
  237.   ok:=gsf_input_read(FStream, Count, @Buffer);
  238.   if not ok then Result:=0 else Result:=Count;
  239.  
  240. end;
  241.  
  242. function TOle2Stream.Seek(Offset: Integer; Origin: Word): Longint;
  243. var
  244.   ok: gboolean;
  245.   Whence: GsfOff_t;
  246. begin
  247.   case Origin of
  248.     soFromBeginning: Whence:=GSF_SEEK_SET;
  249.     soFromCurrent  : Whence:=GSF_SEEK_CUR;
  250.     soFromEnd      : Whence:=GSF_SEEK_END;
  251.     else begin; Result:=-1; exit; end;
  252.   end; //case
  253.  
  254.   if FStorage.FMode= Ole2_Write then
  255.   begin
  256.     ok:=gsf_output_seek(FStream, Offset, Whence);
  257.     if ok then Result:=-1 else Result:=gsf_output_tell(FStream);
  258.   end else
  259.   begin
  260.     ok:=gsf_input_seek(FStream, Offset, Whence);
  261.     if ok then Result:=-1 else Result:=gsf_input_tell(FStream);
  262.   end;
  263. end;
  264.  
  265. function TOle2Stream.Write(const Buffer; Count: Integer): Longint;
  266. var
  267.   ok: boolean;
  268. begin
  269.   if FStorage.FMode= Ole2_Read then raise Exception.Create(ErrCantWriteInStream);
  270.   ok:=gsf_output_write(FStream, Count, @Buffer);
  271.   if not ok then Result:=0 else Result:=Count;
  272. end;
  273. {$ENDIF}
  274.  
  275. initialization
  276.   gsf_init;
  277. finalization
  278.   gsf_shutdown;
  279. end.
  280.