home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / tp6goodi / storage / test.pas < prev   
Encoding:
Pascal/Delphi Source File  |  1991-01-14  |  10.9 KB  |  266 lines

  1. Program StorageTest;
  2.  
  3. { This program will demonstrate the ability to save and restore text info
  4.   in an indexed file that is also Network aware. This should be interesting
  5.  
  6.   Note that the information both stored and retrived are limited to 65530
  7.   characters in length.  In the current version, this will require you to
  8.   have somewhere on your heap that much space. In the future this routine
  9.   will be made EMS aware so that it will grab the best option for heap
  10.   storage and manipulation out there...
  11.  
  12.   The OBJECT TStorage is a Child of the BufStream Object.  This means that
  13.   it still retains all the lower level stuff from BufStream, DOSStream, and
  14.   TStream if you have some sort of use for that.
  15.  
  16.   The routines provided are as follows:
  17.  
  18.   TStorage.Init(FNameStr, Mode, BufSize)
  19.       This routine will initialize the file that you are going to be reading
  20.       from or writing to.  You can use the stCreate, stOpenWrite, stOpenRead,
  21.       or stOpen as your mode.  If you use the stCreate, the system will write
  22.       over your previous file.  If you use stOpenWrite, you can ONLY write
  23.       to the file, you cannot do reads and visa-versa with stOpenRead.  If
  24.       you use stOpen, then you can do both operations at the same time.
  25.  
  26.       This is another item that in the future will be changed to do record
  27.       locking of the specified section you are writing to so that other
  28.       users on a network can read from the various other parts of the file.
  29.  
  30.       The BufSize defines the internal buffer size that the system will use
  31.       to buffer your I/O reads.  Borland recommends around 1024 for standard
  32.       usage.  You might make it bigger or smaller depending on your needs.
  33.  
  34.   TStorage.WriteMsg(Buf)
  35.       This takes a buffer that you define that is NULL terminated (there is
  36.       a #0 at the end of your text) and will write it out to the end of the
  37.       file after running the buffer thru the internal compression routine
  38.       (see TStorage.Compress). It will also set an internal variable
  39.       TStorage.SIndex that is your key to retrieving this body of text.
  40.  
  41.   TStorage.ReadMsg(Buf : PCharBuf; Index)
  42.       This is how you retrieve your text.  You pass the index that you got
  43.       earlier from TStorage.SIndex to this routine and it will pass you a
  44.       buffer that is defined as an array of characters [0..whatever] with
  45.       the string being NULL terminated.  NOTE:  If the index that you pass
  46.       is not the beginning of a stored pattern, the ReadBuf routine will
  47.       assume that you are reading a STANDARD text file and will rewind
  48.       and read the ENTIRE file into the buffer.  This is how you can use
  49.       the same routine to read normal text files as well as those created
  50.       by this Object.  If the message was deleted by the DeleteMsg routine,
  51.       you will get an errorlevel of 100 (Disk Read Error) returned to you
  52.       from the function.
  53.  
  54.   TStorage.DeleteMsg(Index)
  55.       This function does not actually delete the message out of the stream
  56.       as this would then mess up all subsequent index pointers.  Instead, it
  57.       changes the compression routine variable to $FF indicating that the
  58.       message is no longer valid.  To actually take the messages out of the
  59.       stream, you need to use the CleanUpMsg procedure.
  60.  
  61.   TStorage.CleanUpMsg
  62.       This procedure will scan the message stream, and re-write it out to a
  63.       seperate file leaving out all the deleted messages.  It then creates
  64.       a linked list of the old indexes and their new values.  This is then
  65.       used by you, the user, to change all your old saved index values.
  66.       NOTE:  Make sure that you do the index change BEFORE calling the
  67.       TStorage.Done routine as this will remove your list from memory and
  68.       all your pointers will be subsiquently screwed up.  If there is a
  69.       problem and you need to restore the previous file, you can rename
  70.       .$$$ file back to your filename.  The .$$$ file is not deleted until
  71.       the TStorage.Done is called.
  72.  
  73.   TStorage.NewIndex(Index) : LONGINT
  74.       When you call this routine with an old index number, it will return
  75.       to you the new index reference number. You'll get a -1 if the system
  76.       cannot fine an original index number.  To use this, you can scan
  77.       through your recorded indexes in your data file sequentially and call
  78.       this routine with each one you get.  Then replace the old value with
  79.       the new value.  If you get a -1 as your return, then the old message
  80.       was either originally deleted or lost to the system.  This will ALWAYS
  81.       return a -1 if you haven't made a VALID call to TStorage.CleanUpMsg.
  82.       It will also reset after a TStorage.Done has been executed.  Make sure
  83.       that you use this after the TStorage.CleanUpMsg routine if you want
  84.       to retain the changes made.
  85.  
  86.   TStorage.DeleteCleanUp
  87.       If you decide that for some reason something went wrong somewhere and
  88.       everything is screwed up, you can prevent TStorage.Done from replacing
  89.       your original msg file by calling this routine.  It will remove the
  90.       .$$$ file from the disk and clear out all TStorage.NewIndex references.
  91.  
  92.   TStorage.Compress(Buf)
  93.       This is a compression routine that is VERY rudimentary.  I whipped
  94.       this up in an hour or so just to demonstrate how it works.  You can
  95.       create a child object and replace the compress and decompress routines
  96.       with something more efficient if you'd like.  All you need to do is
  97.       create a new RegComp variable other than 1 and make sure that your
  98.       compression routine will downwardly call mine if the numbers don't
  99.       match.  This way you can read files that were created with any
  100.       compression routine that is in the line.
  101.  
  102.   TStorage.DeCompress(Buf)
  103.       Same as the compression except that this goes backwards.  Again, this
  104.       is a basic one that I whipped together in a matter of minutes so don't
  105.       be too impressed by it
  106.  
  107.   TStorage.Done
  108.       Here is where you clean up all the messes, close all the files, and
  109.       return all the used heap back.  Remember to call this when your done
  110.       using the routines
  111.  
  112.   ERRORS Returned
  113.       When you check the TStorage.Status Integer, if you do not get an stOk
  114.       returned, then something went wrong.  To identify it from this Unit,
  115.       You can check TStorage.Status against stStoreError.  Errors also
  116.       included are stStoreReadErr, stStoreWriteErr, and stStoreUnknownErr.
  117.       These are stored in the TStorage.ErrorInfo location.
  118.  
  119.   ---------------------------------------------------------------------------
  120.  
  121.   These routines were originally designed as a message storage routine for a
  122.   new BBS system message base that we are putting together, however we have
  123.   used this storage format for a varity of purposes as you can store variable
  124.   length messages to one file and only have to keep track of an index.  It
  125.   also attempts to save on disk space which is ALWAYS at a premium around
  126.   here.
  127.  
  128.   If you have any suggestions or improvments on this file or its usage, or
  129.   would just like to chat, you can reach me at the following:
  130.  
  131.         Marcos R. Della
  132.         5084 Rincon Ave.
  133.         Santa Rosa, CA 95409
  134.  
  135.         CIS: 71675,765
  136.  
  137.   ---------------------------------------------------------------------------}
  138.  
  139. Uses Dos, Crt, Storage, Objects;
  140.  
  141. VAR   T   : TStorage;
  142.       st1 : STRING;      {Kind of a pseudo buffer}
  143.       st2 : STRING;      {Another pseudo buffer}
  144.       st3 : STRING;
  145.       p   : PCharBuf;    {Pointer to the return character buffer}
  146.  
  147.       idx1   : LONGINT;
  148.       idx2   : LONGINT;
  149.       idx3   : LONGINT;
  150.       loop   : WORD;
  151.       ch     : CHAR;
  152. BEGIN
  153.    CLRSCR;
  154.    st1 := 'Now is the time for all good men to come to the aid of their '
  155.         + 'country before the last of the Mohecians take over the world as '
  156.         + 'we now know it.  This might be a very detrimental accident if '
  157.         + 'it is allowed to happen' + #0;
  158.    st2 := 'This is a message that will test the deletion function.' + #0;
  159.    st3 := 'This message will survive the compression and deletion!' + #0;
  160.  
  161.    T.Init('TESTFILE.DAT',stOpenWrite,512);
  162.    IF T.ErrorInfo = 2 THEN  {File Does Not Exist}
  163.       BEGIN
  164.          T.Done;
  165.          T.Init('TESTFILE.DAT',stCreate,512)
  166.       END;
  167.    WriteLn('Filename:   ',T.SFileName);
  168.    WriteLn('Mode:       ',T.SMode);
  169.  
  170.    T.WriteMsg(st1[1]);    {Our actual buffer is from 1..till we hit the NULL}
  171.    IF T.Status <> stOk THEN    {Do your real error checking here if you are}
  172.       T.Reset;                 {really interested}
  173.    idx1 := T.SIndex;
  174.    WriteLn('1st Index:  ',idx1);
  175.  
  176.    T.WriteMsg(st2[1]);
  177.    IF T.Status <> stOk THEN
  178.       T.Reset;
  179.    idx2 := T.SIndex;
  180.    Writeln('2nd Index:  ',idx2);
  181.  
  182.    T.WriteMsg(st3[1]);
  183.    IF T.Status <> stOk THEN
  184.       T.Reset;
  185.    idx3 := T.SIndex;
  186.    Writeln('3nd Index:  ',idx3);
  187.  
  188.    WriteLn;
  189.    T.DeleteMsg(idx2);
  190.    WriteLn('First Deletion Attempt (Write Only):   ',T.ErrorInfo);
  191.    IF T.Status <> stOk THEN
  192.       T.Reset;
  193.    T.Done;
  194.  
  195.    T.Init('TESTFILE.DAT',stOpen,128);
  196.    T.DeleteMsg(idx2);            {Must be open for read/write!}
  197.    WriteLn('Second Deletion Attempt (Read/Write):  ',T.ErrorInfo);
  198.    IF T.Status <> stOk THEN
  199.       T.Reset;
  200.  
  201.    T.ReadMsg(p,idx2);
  202.    WriteLn('Attempt to re-read:                    ',T.ErrorInfo);
  203.    IF T.Status <> stOk THEN
  204.       T.Reset;
  205.    Write('"');
  206.    Loop := 0;
  207.    WHILE p^[Loop] <> #0 DO BEGIN
  208.       Write(p^[Loop]);
  209.       INC(Loop)
  210.    END;
  211.    WriteLn('"');
  212.    Write('Cleaning up the deletion files.   Error returned: ');
  213.    T.CleanUpMsg;
  214.    WriteLn(T.ErrorInfo);
  215.    WriteLn('Re-Index of #1 (Old/New):   ',idx1,'/',T.NewIndex(idx1));
  216.    WriteLn('Re-Index of #2:             ',idx2,'/',T.NewIndex(idx2));
  217.    WriteLn('Re-Index of #3:             ',idx3,'/',T.NewIndex(idx3));
  218.    WriteLn;
  219.    WriteLn('Removing Cleanup stuff and restoring old indexes');
  220.    T.DeleteCleanUp;
  221.    T.Done;
  222.  
  223.    T.Init('TESTFILE.DAT',stOpenRead,128);
  224.    T.ReadMsg(p,idx1);
  225.    WriteLn('Test that is being read back from the file:');
  226.    WriteLn('---------------Index 1----------------------------');
  227.    Loop := 0;
  228.    WHILE p^[Loop] <> #0 DO BEGIN
  229.       Write(p^[Loop]);
  230.       INC(Loop)
  231.    END;
  232.    WriteLn;
  233.    WriteLn;
  234.  
  235.    T.ReadMsg(p,idx3);
  236.    WriteLn('---------------Index 3----------------------------');
  237.    Loop := 0;
  238.    WHILE p^[Loop] <> #0 DO BEGIN
  239.       Write(p^[Loop]);
  240.       INC(Loop)
  241.    END;
  242.    T.Done;
  243.  
  244.    WriteLn;
  245.    WriteLn('-------------------------------------------');
  246.    WriteLn('If you want to see what the compressed text looks like');
  247.    WriteLn('then use a listing utility to list the file ',T.SFilename);
  248.    WriteLn;
  249.    WriteLn('Press a key to read a STANDARD text file');
  250.    ch := READKEY;
  251.    IF ch = #0 THEN
  252.       ch := READKEY;
  253.    CLRSCR;
  254.  
  255.    T.Init('TEST.PAS',stOpenRead,1024);
  256.    T.ReadMsg(p,0);
  257.    Loop := 0;
  258.    WHILE p^[Loop] <> #0 DO BEGIN
  259.       Write(p^[Loop]);
  260.       INC(Loop)
  261.    END;
  262.    WriteLn;
  263.    T.Done;
  264. END.
  265.  
  266.