home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 March / Chip_2002-03_cd1.bin / zkuste / delphi / kompon / d3456 / EHS.ZIP / setup.exe / {app} / ehscontextmap.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  2001-11-26  |  7.5 KB  |  255 lines

  1. { THelpContextMap
  2.  
  3.   Delphi 3/4/5/6 Implementation of a storage container for help context numbers.
  4.  
  5.   ⌐ 2000-2001 EC Software. All rights reserved.
  6.  
  7.   This product and it's source code is protected by patents, copyright laws and
  8.   international copyright treaties, as well as other intellectual property
  9.   laws and treaties. The product is licensed, not sold.
  10.  
  11.   The source code and sample programs in this package or parts hereof
  12.   as well as the documentation shall not be copied, modified or redistributed
  13.   without permission, explicit or implied, of the author.
  14.  
  15.  
  16.   EMail: info@ec-software.com
  17.   Internet: http://www.ec-software.com
  18.  
  19.   Disclaimer of Warranty
  20.   ----------------------
  21.  
  22.   THIS SOFTWARE AND THE ACCOMPANYING FILES ARE PROVIDED "AS IS" AND
  23.   WITHOUT WARRANTIES OF ANY KIND WHETHER EXPRESSED OR IMPLIED.
  24.  
  25.   In no event shall the author be held liable for any damages whatsoever,
  26.   including without limitation, damages for loss of business profits,
  27.   business interruption, loss of business information, or any other loss
  28.   arising from the use or inability to use the software. }
  29.  
  30. unit ehscontextmap;
  31.  
  32. interface
  33.  
  34. uses
  35.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
  36.  
  37. type
  38.    PContextPair = ^TContextPair;
  39.    TContextPair = record
  40.      HashVal: longint;
  41.      CntxVal: THelpContext;
  42.    end;
  43.  
  44.   THelpContextMap = class(TComponent)
  45.   private
  46.     fFileName: TFileName;
  47.     fData: TMemoryStream;
  48.     procedure SetFileName(value: TFilename);
  49.   protected
  50.     procedure DefineProperties(Filer: TFiler); override;
  51.     procedure ReadFileData(Stream: TStream); virtual;
  52.     procedure WriteFileData(Stream: TStream); virtual;
  53.   public
  54.     constructor Create(AOwner: TComponent); override;
  55.     destructor  Destroy; override;
  56.     function    GetContext(TopicID: string): THelpContext;
  57.   published
  58.     property FileName: TFileName read fFileName write SetFileName;
  59.   end;
  60.  
  61. implementation
  62.  
  63. uses ehshshtb;
  64.  
  65.  
  66. constructor THelpContextMap.Create(AOwner: TComponent);
  67. begin
  68.      inherited Create(AOwner);
  69.      fData := TMemoryStream.create;
  70. end;
  71.  
  72. destructor THelpContextMap.Destroy;
  73. begin
  74.      fData.free;
  75.      inherited Destroy;
  76. end;
  77.  
  78. procedure THelpContextMap.DefineProperties(Filer: TFiler);
  79. begin
  80.      inherited DefineProperties(Filer);
  81.      Filer.DefineBinaryProperty('FileData', ReadFileData, WriteFileData, (fData.size > 0));
  82. end;
  83.  
  84. procedure THelpContextMap.ReadFileData(Stream: TStream);
  85. var
  86.    Size: longint;
  87. begin
  88.      fData.clear;
  89.      Stream.ReadBuffer(Size, SizeOf(Size));
  90.      fData.CopyFrom(Stream, Size);
  91. end;
  92.  
  93. procedure THelpContextMap.WriteFileData(Stream: TStream);
  94. var
  95.    Size: longint;
  96. begin
  97.      fData.seek(0,0);
  98.      Size := fData.size;
  99.      Stream.WriteBuffer(Size, SizeOf(Size));
  100.      Stream.CopyFrom(fData, Size);
  101. end;
  102.  
  103. procedure THelpContextMap.SetFileName(value: TFilename);
  104. var
  105.    CList: TList;
  106.    L: integer;
  107.  
  108.    procedure ParseFile(const fname: string; IsIncludeFile: boolean);
  109.    var
  110.      IsMap: boolean;
  111.      f: Textfile;
  112.      s: string;
  113.      h, c: string;
  114.      i, hi, ci: integer;
  115.      hval: boolean;
  116.      P: PContextPair;
  117.      LastDir, ExpandedName: string;
  118.    begin
  119.      assignFile(f, fname);
  120.      reset(f);
  121.      try
  122.        IsMap := false;
  123.        while not eof(f) do
  124.        begin
  125.           readln(f, s);
  126.           s := trim(s);
  127.           if (IsMap or IsIncludeFile) and (s <> '') then
  128.           begin
  129.              if strLcomp('[',pchar(s),1) = 0 then exit;  //break
  130.  
  131.              if strLcomp('#include',pchar(s),8) = 0 then  //parse include file
  132.              begin
  133.                   LastDir := GetCurrentDir;
  134.                   SetCurrentDir(ExtractFileDir(fname));
  135.                   ExpandedName := ExpandFileName(trim(copy(s, 9, length(s)-8)));
  136.                   if FileExists(ExpandedName)
  137.                     then ParseFile(ExpandedName, true)
  138.                     else MessageDlg('Include file "'+ExpandedName+'" not found!', mtError, [mbOK], 0);
  139.                   SetCurrentDir(LastDir);
  140.              end
  141.              else begin
  142.                if strLcomp('#define',pchar(s),7) = 0 then s := copy(s,9,length(s)-8);
  143.                hval := true;
  144.                h := '';
  145.                c := '';
  146.                for i := 1 to length(s) do
  147.                begin
  148.                     case s[i] of
  149.                     ';','#': break;
  150.                     '=':     hval := false;
  151.                     #9,#32:  if h <> '' then hval := false;
  152.                     else
  153.                       begin
  154.                          if hval then h := h + s[i]
  155.                                  else c := c + s[i];
  156.                       end;
  157.                     end;
  158.                end;
  159.                if (h <> '') and (c <> '') then
  160.                try
  161.                   ci := strtoint(c);
  162.                   hi := GetHashValue(h);
  163.                   if hi <> 0 then
  164.                   begin
  165.                        New(P);
  166.                        P^.hashval := hi;
  167.                        P^.cntxval := ci;
  168.                        Clist.add(P);
  169.                   end;
  170.                except;
  171.                end;
  172.              end;
  173.           end  //IsMap
  174.           else IsMap := strLcomp('[MAP]',pchar(s),5) = 0;
  175.        end;
  176.      finally
  177.        closefile(f);
  178.      end;
  179.    end;
  180.  
  181.    function CBCListSort(Item1, Item2: Pointer): Integer;
  182.    begin
  183.         result := 0;
  184.         if PContextPair(Item1)^.HashVal < PContextPair(Item2)^.HashVal then result := -1
  185.         else if PContextPair(Item1)^.HashVal > PContextPair(Item2)^.HashVal then result := 1;
  186.    end;
  187.  
  188. begin
  189.      if (value <> '')
  190.        and (not (csLoading in ComponentState))
  191.        and (not (csReading in ComponentState)) then
  192.      try
  193.         if (value <> '') and (not FileExists(value)) then
  194.         begin
  195.           raise Exception.create('File '+value+' not found.');
  196.           fData.clear;
  197.           exit;
  198.         end;
  199.  
  200.  
  201.         fData.clear;
  202.         CList := TList.create;
  203.         ParseFile(value, false);
  204.         CList.sort(@CBCListSort);
  205.         for L := 0 to CList.count-1 do
  206.         begin
  207.              fData.WriteBuffer(PContextPair(CList[L])^.HashVal, sizeof(longint));
  208.              fData.WriteBuffer(PContextPair(CList[L])^.CntxVal, sizeof(THelpContext));
  209.         end;
  210.         if (csDesigning in ComponentState)
  211.           then MessageDlg('Help context list updated. '
  212.                           +inttostr(CList.count)
  213.                           +' items stored.',
  214.                           mtInformation, [mbOK], 0);
  215.      finally
  216.         for L := 0 to CList.count-1 do Dispose(PContextPair(CList[L]));
  217.         CList.free;
  218.      end;
  219.      fFilename := value;
  220. end;
  221.  
  222. function THelpContextMap.GetContext(TopicID: string): THelpContext;
  223. var
  224.    rclen: integer;
  225.    L, R, M: integer;
  226.    Hi, HashVal: longint;
  227. begin
  228.      result := 0;
  229.      HashVal := GetHashValue(TopicID);
  230.      if (HashVal <> 0) and (fData <> nil) and (fData.size > 0) then
  231.      begin
  232.           rclen := sizeof(longint) + sizeof(THelpContext);
  233.  
  234.           L := 0;
  235.           R := pred(fData.size div rclen);
  236.           while L <= R do
  237.           begin
  238.                M := (L + R) div 2;
  239.                fData.seek(M * rclen, soFromBeginning);
  240.  
  241.                fData.readbuffer(Hi, sizeof(Hi));
  242.                if Hi = Hashval then
  243.                begin
  244.                     fData.readbuffer(result, sizeof(result));
  245.                     exit;
  246.                end
  247.                else
  248.                  if (Hi < HashVal) then L := M + 1
  249.                                    else R := M - 1;
  250.           end;
  251.      end;
  252. end;
  253.  
  254. end.
  255.