home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 073.lha / FileIO / fileio.c < prev    next >
C/C++ Source or Header  |  1987-06-02  |  15KB  |  470 lines

  1.     
  2. /* *** fileio.c *************************************************************
  3.  *
  4.  * File IO Suite  --  Primary FileIO Requester Routines
  5.  *     from Book 1 of the Amiga Programmers' Suite by RJ Mical
  6.  *
  7.  * Copyright (C) 1986, 1987, Robert J. Mical
  8.  * All Rights Reserved.
  9.  *
  10.  * Created for Amiga developers.
  11.  * Any or all of this code can be used in any program as long as this
  12.  * entire copyright notice is retained, ok?  Thanks.
  13.  *
  14.  * HISTORY      NAME            DESCRIPTION
  15.  * -----------  --------------  --------------------------------------------
  16.  * 4 Feb 87     RJ              Real release
  17.  * 12 Aug 86    RJ >:-{)*       Prepare (clean house) for release
  18.  * 3 May 86     =RJ Mical=      Fix prop gadget for both 1.1 and 1.2
  19.  * 1 Feb 86     =RJ Mical=      Created this file.
  20.  *
  21.  * *********************************************************************** */
  22.  
  23.  
  24. #define FILEIO_SOURCEFILE
  25. #include "fileio.h"
  26.  
  27.  
  28. /* These routines can be found in filesupp.c */
  29. extern HandleGadget();
  30. extern StartOpenRequester();
  31. extern DiskInserted();
  32. extern PropMouseMoves();
  33.  
  34.  
  35.  
  36. /* *** GetFileIOSupport() ***************************************************
  37.  * 
  38.  * NAME
  39.  *     GetFileIOSupport  --  Allocate and initialize a FileIOSupport structure
  40.  * 
  41.  * 
  42.  * SYNOPSIS
  43.  *     struct FileIOSupport *GetFileIOSupport();
  44.  * 
  45.  * 
  46.  * FUNCTION
  47.  *     Allocates and initializes a FileIOSupport structure for use with
  48.  *     calls to GetFileIOName().
  49.  * 
  50.  *     You may want to further initialize the structure before calling
  51.  *     GetFileIOName().  Refer to the FileIO documentation for more
  52.  *     information.
  53.  * 
  54.  *     When you're done with the structure, call ReleaseFileIO().
  55.  * 
  56.  * 
  57.  * INPUTS
  58.  *     None
  59.  * 
  60.  * 
  61.  * RESULT
  62.  *     If all goes well, returns the address of a FileIOSupport structure.
  63.  *     If anything goes wrong (usually out of memory), returns NULL.
  64.  * 
  65.  * 
  66.  * EXAMPLE
  67.  *     struct FileIOSupport *fileio;
  68.  *     fileio = GetFileIOSupport();
  69.  *     GetFileIOName(fileio, window);
  70.  *     ReleaseFileIO(fileio);
  71.  * 
  72.  * 
  73.  * BUGS
  74.  *     None known
  75.  * 
  76.  * 
  77.  * SEE ALSO
  78.  *     GetFileIOName(), ReleaseFileIO()
  79.  */
  80. struct FileIOSupport *GetFileIOSupport()
  81. {
  82.     struct FileIOSupport *fileio;
  83.  
  84.     if (fileio = (struct FileIOSupport *)AllocMem(
  85.             sizeof(struct FileIOSupport), MEMF_CLEAR))
  86.         {
  87.         /* Anything special to initialize? */
  88.         SetFlag(fileio->Flags, USE_VOLUME_NAMES);
  89.         }
  90.     return(fileio);
  91. }
  92.  
  93.  
  94.  
  95. /* *** GetFileIOName() ******************************************************
  96.  * 
  97.  * NAME
  98.  *     GetFileIOName  --  Gets a file name for input/output from the user
  99.  * 
  100.  * 
  101.  * SYNOPSIS
  102.  *     BOOL GetFileIOName(FileIO, Window);
  103.  * 
  104.  * 
  105.  * FUNCTION
  106.  *     This routine creates a filename requester which allows the user
  107.  *     to browse through the AmigaDOS filesystem and select one of
  108.  *     the filenames found there.
  109.  * 
  110.  *     The FileIO argument is a pointer to a FileIOSupport structure,
  111.  *     which is allocated and initialized for you via a call to 
  112.  *     GetFileIOSupport().
  113.  *     You may preset the FileIO parameters before calling this routine, 
  114.  *     or you may leave them set at their default values.  See the FileIO
  115.  *     documentation for complete details.
  116.  * 
  117.  *     The Window argument is the pointer to the window structure returned
  118.  *     by a call to Intuition's OpenWindow() function.  As this routine
  119.  *     opens a requester and requesters open in windows, you must have
  120.  *     already opened a window before calling this routine, even if it's
  121.  *     a window opened for no other purpose than to call this routine.
  122.  * 
  123.  *     This routine returns a BOOL value of TRUE or FALSE, depending on
  124.  *     whether the user chose to accept or cancel the filename selection 
  125.  *     operation.  If TRUE, the filename selected by the user can be
  126.  *     found in the FileIO structure FileName[] field.  This filename
  127.  *     will have all leading and trailing blanks removed (in case the
  128.  *     user typed in a filename with extraneous spaces).  Likewise,
  129.  *     the pathname to the disk and drawer can be found in the text
  130.  *     fields DiskName[] and DrawerName[].  You can construct 
  131.  *     the pathname using these text strings.  Also, you can call 
  132.  *     BuildFileIOPathname() to build the pathname automatically.
  133.  * 
  134.  *     There's a *lot* more to be said about this function.  Please 
  135.  *     read the documentation.
  136.  * 
  137.  *     NOTE:  This routine is not re-entrant.  What this means 
  138.  *     is that if you have created a program that has more than one task,
  139.  *     this routine cannot be called by more than one task at a time.
  140.  *     This is not a problem for the grand majority of programs.
  141.  *     But if you have some application that would require calling this 
  142.  *     routine asynchronously from multiple tasks, you'll have to 
  143.  *     implement some quick semaphore arrangement to avoid collisions.
  144.  *     No big deal, actually.  See Exec semaphores for everything you need.
  145.  * 
  146.  * 
  147.  * INPUTS
  148.  *     FileIO = pointer to a FileIOSupport structure, as allocated
  149.  *         via a call to GetFileIOSupport()
  150.  *     Window = pointer to a Window structure, as created via a call
  151.  *         to Intuition's OpenWindow()
  152.  * 
  153.  * 
  154.  * RESULT
  155.  *     TRUE if the user decided that the filename selection was successful,
  156.  *     FALSE if the user chose to cancel the operation
  157.  * 
  158.  * 
  159.  * EXAMPLE
  160.  *     if (GetFileIOName(fileio, window))
  161.  *         ProcessFileName(&fileio->FileName[0]);
  162.  * 
  163.  * 
  164.  * BUGS
  165.  *     None known, though there could be some, and the disk selection
  166.  *     subsystem logic is not perfectly polished (though it's believed 
  167.  *     to be bug-free).
  168.  * 
  169.  * 
  170.  * SEE ALSO
  171.  *     BuildFileIOPathname(), GetFileIOSupport(), ReleaseFileIO()
  172.  */
  173. BOOL GetFileIOName(fileio, window)
  174. struct FileIOSupport *fileio;
  175. struct Window *window;
  176. {
  177.     UBYTE *newtext;
  178.  
  179.     if ((fileio == NULL) || (window == NULL)) return(FALSE);
  180.  
  181.     OpenSaveLock = CurrentDir(NULL);
  182.     CurrentDir(OpenSaveLock);
  183.     fileio->DOSLock = OpenSaveLock;
  184.  
  185.     /* Get easily-accessible copies of the values that are referenced 
  186.      * most often
  187.      */
  188.     OpenReq = &OpenReqSupport.Requester;
  189.     OpenReqWindow = OpenReqSupport.Window = window;
  190.     OpenReqFileIO = fileio;
  191.  
  192.     /* Set up the DoRequest() handlers */
  193.     OpenReqSupport.GadgetHandler = HandleGadget;
  194.     OpenReqSupport.StartRequest = StartOpenRequester;
  195.     OpenReqSupport.NewDiskHandler = DiskInserted;
  196.     OpenReqSupport.MouseMoveHandler = PropMouseMoves;
  197.  
  198.     /* Init the string gadget buffers */
  199.     OpenNameTextInfo.Buffer = &fileio->FileName[0];
  200.     OpenDrawerTextInfo.Buffer = &fileio->DrawerName[0];
  201.     OpenDiskTextInfo.Buffer = &fileio->DiskName[0];
  202.  
  203.     /* Initialize the requester title */
  204.     if ((ReqTitleText.IText = fileio->ReqTitle) == NULL)
  205.         ReqTitleText.IText = DefaultReqTitle;
  206.     ReqTitleText.LeftEdge
  207.         = (OPEN_WIDTH - IntuiTextLength(&ReqTitleText)) >> 1;
  208.  
  209.     /* If this fileio doesn't have valid filenames,
  210.      * then refresh the whole thing
  211.      */
  212.     if (FlagIsClear(fileio->Flags, GOOD_FILENAMES))
  213.         {
  214.         ResetNameText(TRUE);
  215.         ResetDrawerText(TRUE);
  216.         BuildVolumeTable(fileio);
  217.         CopyString(&OpenReqFileIO->DiskName[0], CurrentVolumeName());
  218.         }
  219.  
  220.     ResetNameText(FALSE);
  221.     ResetDrawerText(FALSE);
  222.     ResetDiskText(FALSE);
  223.  
  224.     StuffSelectNames(0);
  225.     InitOpenProp(TRUE);
  226.  
  227.     /* Reset the double-click time variables */
  228.     OpenClickSeconds = OpenClickMicros = 0;
  229.  
  230.  
  231.     /* And now, do that requester. */
  232.     DoRequest(&OpenReqSupport);
  233.     /* Back, eh?  Wasn't that easy? */
  234.  
  235.  
  236.     if (FlagIsSet(fileio->Flags, LOCK_GOTTEN))
  237.         {
  238.         UnLock(fileio->DOSLock);
  239.         ClearFlag(fileio->Flags, LOCK_GOTTEN);
  240.         }
  241.  
  242.     CurrentDir(OpenSaveLock);
  243.     OpenReqFileIO = NULL;
  244.  
  245.     /* Strip any excess leading and trailing blanks off the final name */
  246.     newtext = StripOuterSpace(&fileio->FileName[0], " ");
  247.     CopyString(&fileio->FileName[0], newtext);
  248.  
  249.     if (OpenReqSupport.SelectedGadgetID != OPENGADGET_CANCEL)
  250.         return(TRUE);
  251.     return(FALSE);
  252. }
  253.  
  254.  
  255.  
  256. /* *** BuildFileIOPathname() ************************************************
  257.  * 
  258.  * NAME
  259.  *     BuildFileIOPathname  --  Build a file pathname using a FileIO struct
  260.  * 
  261.  * 
  262.  * SYNOPSIS
  263.  *     BuildFileIOPathname(FileIOSupport, Buffer);
  264.  * 
  265.  * 
  266.  * FUNCTION
  267.  *     Builds the text for a pathname using the FileName[], DrawerName[] and
  268.  *     DiskName[] fields of the specified FileIOSupport structure
  269.  *     after the support structure has been used in a successful call
  270.  *     to GetFileIOName().  Writes the text into the Buffer.
  271.  * 
  272.  * 
  273.  * INPUTS
  274.  *     FileIOSupport = the address of a FileIOSupport structure
  275.  *     Buffer = address of the buffer to receive the file pathname
  276.  * 
  277.  * 
  278.  * RESULT
  279.  *     None
  280.  * 
  281.  * 
  282.  * SEE ALSO
  283.  *     GetFileIOName()
  284.  */
  285. VOID BuildFileIOPathname(fileio, buffer)
  286. struct FileIOSupport *fileio;
  287. UBYTE *buffer;
  288. {
  289.     StripOuterSpace(&fileio->DiskName[0], " ");
  290.     StripOuterSpace(&fileio->DrawerName[0], " ");
  291.     StripOuterSpace(&fileio->FileName[0], " ");
  292.  
  293.     CopyString(buffer, &fileio->DiskName[0]);
  294.     if (StringLength(&fileio->DrawerName[0]))
  295.         {
  296.         ConcatString(buffer, &fileio->DrawerName[0]);
  297.         ConcatString(buffer, "/");
  298.         }
  299.     ConcatString(buffer, &fileio->FileName[0]);
  300. }
  301.  
  302.  
  303.  
  304. /* *** AddFileIOName() ******************************************************
  305.  * 
  306.  * NAME
  307.  *     AddFileIOName  --  Add a file name to the names in a FileIOSupport
  308.  * 
  309.  * 
  310.  * SYNOPSIS
  311.  *     AddFileIOName(FileIOSupport, FileName);
  312.  * 
  313.  * 
  314.  * FUNCTION
  315.  *     This routine adds a file name to the list of file names currently 
  316.  *     in the specified FileIOSupport structure.  The next time the 
  317.  *     FileIOSupport structure is used for a call to GetFileIOName(), the 
  318.  *     new file name will apppear alphabetized in with the other file names.  
  319.  *     
  320.  *     This routine will most often be used after a call to GetFileIOName() 
  321.  *     or some other routine where the user is allowed to specify the name 
  322.  *     of a file to be opened for output.  If the file is opened 
  323.  *     successfully, this routine will make sure that the name of the file 
  324.  *     is in the FileIOSupport structure.  This is important if the output 
  325.  *     file has been newly created; otherwise, without calling this 
  326.  *     routine, the next time the FileIOSupport structure is used the new 
  327.  *     file name would not appear even though the file exists.  If the name 
  328.  *     is already in the list when you call AddFileIOName() then nothing 
  329.  *     happens.  This allows you to call AddFileIOName() without worrying 
  330.  *     about duplicate name redundancy.
  331.  *     
  332.  *     Here's a typical sequence of events leading up to a call to 
  333.  *     AddFileIOName():
  334.  *     
  335.  *         First, get a FileIOSupport structure:
  336.  *             fileio = GetFileIOSupport(...);
  337.  *     
  338.  *         When the user wants to write data, use GetFileIOName()
  339.  *         to provide a convenient and consistent interface to
  340.  *         the filesystem:
  341.  *             goodfile = GetFileIOName(...);
  342.  *     
  343.  *         If the user has selected a name for output (in this example,
  344.  *         goodfile will equal TRUE if the user selected a name), then
  345.  *         open the file (possibly creating it) and then call 
  346.  *         AddFileIOName() to make sure the name is in the FileIOSupport
  347.  *         structure's list:
  348.  *             if (goodfile)
  349.  *                 {
  350.  *                 UBYTE filename[80];
  351.  *                 
  352.  *                 BuildFileIOPathname(fileio, &filename[0]);
  353.  *                 ... open filename, write it, close it ...
  354.  *                 if (filename opened successfully)
  355.  *                     AddFileIOName(fileio, &filename[0]);
  356.  *                 }
  357.  * 
  358.  * 
  359.  * INPUTS
  360.  *     FileIOSupport = the address of a FileIOSupport structure
  361.  *     FileName = the address of null-terminated text that is
  362.  *         either a simple file name or a valid AmigaDOS pathname.
  363.  * 
  364.  * 
  365.  * RESULT
  366.  *     None
  367.  * 
  368.  * 
  369.  * SEE ALSO
  370.  *     GetFileIOName()
  371.  *     GetFileIOSupport()
  372.  */
  373. VOID AddFileIOName(fileio, filename)
  374. struct FileIOSupport *fileio;
  375. UBYTE *filename;
  376. {
  377.     SHORT index, i, length;
  378.     struct Remember *remember, *oldremember;
  379.     UBYTE *nextentry;
  380.     struct Remember *namekey;
  381.  
  382.     /* Does the filename start with a volume name?  If so, skip over it */
  383.     index = IndexString(filename, ":");
  384.     if (index >= 0) filename += index + 1;
  385.  
  386.     /* Does the filename start with a directory name?  If so, skip over it */
  387.     do 
  388.         {
  389.         index = IndexString(filename, "/");
  390.         if (index >= 0) filename += index + 1;
  391.         }
  392.     while (index >= 0);
  393.  
  394.     if (*filename == 0) return;
  395.  
  396.     /* Here, filename points to what is presumed to be a valid file name.
  397.      * If it's found among the FileIOSupport's names, exit.
  398.      * If it's not found in the list, add it.
  399.      *
  400.      * The current file names are stored in the fileio's Remember list.
  401.      */
  402.     remember = fileio->NameKey;
  403.     oldremember = NULL;
  404.     while (remember)
  405.         {
  406.         i = CompareUpperStrings(filename, remember->Memory);
  407.         if (i < 0) goto ADD_FILENAME;
  408.         if (i == 0) return;
  409.         oldremember = remember;
  410.         remember = remember->NextRemember;
  411.         }
  412.  
  413. ADD_FILENAME:
  414.     /* Name not on list, so add it now */
  415.     length = StringLength(filename);
  416.  
  417.     namekey = NULL;
  418.     if (nextentry = AllocRemember(&namekey, length + 1 + 1, NULL))
  419.         {
  420.         CopyString(nextentry, filename);
  421.         *(nextentry + length + 1) = 0;
  422.         if (oldremember) oldremember->NextRemember = namekey;
  423.         else fileio->NameKey = namekey;
  424.         /* This assignment is valid whether or not remember is NULL */
  425.         namekey->NextRemember = remember;
  426.         fileio->NameCount++;
  427.         }
  428. }
  429.  
  430.  
  431.  
  432. /* *** ReleaseFileIO() ******************************************************
  433.  * 
  434.  * NAME
  435.  *     ReleaseFileIO  --  Release the FileIO structure and all local memory
  436.  * 
  437.  * 
  438.  * SYNOPSIS
  439.  *     ReleaseFileIO(FileIO);
  440.  * 
  441.  * 
  442.  * FUNCTION
  443.  *     Releases the FileIO structure by freeing all local memory attached
  444.  *     to the structure and then freeing the structure itself.
  445.  * 
  446.  * 
  447.  * INPUTS
  448.  *     FileIO = the address of a FileIO structure
  449.  * 
  450.  * 
  451.  * RESULT
  452.  *     None
  453.  * 
  454.  * 
  455.  * SEE ALSO
  456.  *     GetFileIOSupport()
  457.  */
  458. VOID ReleaseFileIO(fileio)
  459. struct FileIOSupport *fileio;
  460. {
  461.     if (fileio)
  462.         {
  463.         FreeRemember(&fileio->VolumeKey, TRUE);
  464.         FreeRemember(&fileio->NameKey, TRUE);
  465.         FreeMem(fileio, sizeof(struct FileIOSupport));
  466.         }
  467. }
  468.  
  469.  
  470.