home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
073.lha
/
FileIO
/
fileio.c
< prev
next >
Wrap
C/C++ Source or Header
|
1987-06-02
|
15KB
|
470 lines
/* *** fileio.c *************************************************************
*
* File IO Suite -- Primary FileIO Requester Routines
* from Book 1 of the Amiga Programmers' Suite by RJ Mical
*
* Copyright (C) 1986, 1987, Robert J. Mical
* All Rights Reserved.
*
* Created for Amiga developers.
* Any or all of this code can be used in any program as long as this
* entire copyright notice is retained, ok? Thanks.
*
* HISTORY NAME DESCRIPTION
* ----------- -------------- --------------------------------------------
* 4 Feb 87 RJ Real release
* 12 Aug 86 RJ >:-{)* Prepare (clean house) for release
* 3 May 86 =RJ Mical= Fix prop gadget for both 1.1 and 1.2
* 1 Feb 86 =RJ Mical= Created this file.
*
* *********************************************************************** */
#define FILEIO_SOURCEFILE
#include "fileio.h"
/* These routines can be found in filesupp.c */
extern HandleGadget();
extern StartOpenRequester();
extern DiskInserted();
extern PropMouseMoves();
/* *** GetFileIOSupport() ***************************************************
*
* NAME
* GetFileIOSupport -- Allocate and initialize a FileIOSupport structure
*
*
* SYNOPSIS
* struct FileIOSupport *GetFileIOSupport();
*
*
* FUNCTION
* Allocates and initializes a FileIOSupport structure for use with
* calls to GetFileIOName().
*
* You may want to further initialize the structure before calling
* GetFileIOName(). Refer to the FileIO documentation for more
* information.
*
* When you're done with the structure, call ReleaseFileIO().
*
*
* INPUTS
* None
*
*
* RESULT
* If all goes well, returns the address of a FileIOSupport structure.
* If anything goes wrong (usually out of memory), returns NULL.
*
*
* EXAMPLE
* struct FileIOSupport *fileio;
* fileio = GetFileIOSupport();
* GetFileIOName(fileio, window);
* ReleaseFileIO(fileio);
*
*
* BUGS
* None known
*
*
* SEE ALSO
* GetFileIOName(), ReleaseFileIO()
*/
struct FileIOSupport *GetFileIOSupport()
{
struct FileIOSupport *fileio;
if (fileio = (struct FileIOSupport *)AllocMem(
sizeof(struct FileIOSupport), MEMF_CLEAR))
{
/* Anything special to initialize? */
SetFlag(fileio->Flags, USE_VOLUME_NAMES);
}
return(fileio);
}
/* *** GetFileIOName() ******************************************************
*
* NAME
* GetFileIOName -- Gets a file name for input/output from the user
*
*
* SYNOPSIS
* BOOL GetFileIOName(FileIO, Window);
*
*
* FUNCTION
* This routine creates a filename requester which allows the user
* to browse through the AmigaDOS filesystem and select one of
* the filenames found there.
*
* The FileIO argument is a pointer to a FileIOSupport structure,
* which is allocated and initialized for you via a call to
* GetFileIOSupport().
* You may preset the FileIO parameters before calling this routine,
* or you may leave them set at their default values. See the FileIO
* documentation for complete details.
*
* The Window argument is the pointer to the window structure returned
* by a call to Intuition's OpenWindow() function. As this routine
* opens a requester and requesters open in windows, you must have
* already opened a window before calling this routine, even if it's
* a window opened for no other purpose than to call this routine.
*
* This routine returns a BOOL value of TRUE or FALSE, depending on
* whether the user chose to accept or cancel the filename selection
* operation. If TRUE, the filename selected by the user can be
* found in the FileIO structure FileName[] field. This filename
* will have all leading and trailing blanks removed (in case the
* user typed in a filename with extraneous spaces). Likewise,
* the pathname to the disk and drawer can be found in the text
* fields DiskName[] and DrawerName[]. You can construct
* the pathname using these text strings. Also, you can call
* BuildFileIOPathname() to build the pathname automatically.
*
* There's a *lot* more to be said about this function. Please
* read the documentation.
*
* NOTE: This routine is not re-entrant. What this means
* is that if you have created a program that has more than one task,
* this routine cannot be called by more than one task at a time.
* This is not a problem for the grand majority of programs.
* But if you have some application that would require calling this
* routine asynchronously from multiple tasks, you'll have to
* implement some quick semaphore arrangement to avoid collisions.
* No big deal, actually. See Exec semaphores for everything you need.
*
*
* INPUTS
* FileIO = pointer to a FileIOSupport structure, as allocated
* via a call to GetFileIOSupport()
* Window = pointer to a Window structure, as created via a call
* to Intuition's OpenWindow()
*
*
* RESULT
* TRUE if the user decided that the filename selection was successful,
* FALSE if the user chose to cancel the operation
*
*
* EXAMPLE
* if (GetFileIOName(fileio, window))
* ProcessFileName(&fileio->FileName[0]);
*
*
* BUGS
* None known, though there could be some, and the disk selection
* subsystem logic is not perfectly polished (though it's believed
* to be bug-free).
*
*
* SEE ALSO
* BuildFileIOPathname(), GetFileIOSupport(), ReleaseFileIO()
*/
BOOL GetFileIOName(fileio, window)
struct FileIOSupport *fileio;
struct Window *window;
{
UBYTE *newtext;
if ((fileio == NULL) || (window == NULL)) return(FALSE);
OpenSaveLock = CurrentDir(NULL);
CurrentDir(OpenSaveLock);
fileio->DOSLock = OpenSaveLock;
/* Get easily-accessible copies of the values that are referenced
* most often
*/
OpenReq = &OpenReqSupport.Requester;
OpenReqWindow = OpenReqSupport.Window = window;
OpenReqFileIO = fileio;
/* Set up the DoRequest() handlers */
OpenReqSupport.GadgetHandler = HandleGadget;
OpenReqSupport.StartRequest = StartOpenRequester;
OpenReqSupport.NewDiskHandler = DiskInserted;
OpenReqSupport.MouseMoveHandler = PropMouseMoves;
/* Init the string gadget buffers */
OpenNameTextInfo.Buffer = &fileio->FileName[0];
OpenDrawerTextInfo.Buffer = &fileio->DrawerName[0];
OpenDiskTextInfo.Buffer = &fileio->DiskName[0];
/* Initialize the requester title */
if ((ReqTitleText.IText = fileio->ReqTitle) == NULL)
ReqTitleText.IText = DefaultReqTitle;
ReqTitleText.LeftEdge
= (OPEN_WIDTH - IntuiTextLength(&ReqTitleText)) >> 1;
/* If this fileio doesn't have valid filenames,
* then refresh the whole thing
*/
if (FlagIsClear(fileio->Flags, GOOD_FILENAMES))
{
ResetNameText(TRUE);
ResetDrawerText(TRUE);
BuildVolumeTable(fileio);
CopyString(&OpenReqFileIO->DiskName[0], CurrentVolumeName());
}
ResetNameText(FALSE);
ResetDrawerText(FALSE);
ResetDiskText(FALSE);
StuffSelectNames(0);
InitOpenProp(TRUE);
/* Reset the double-click time variables */
OpenClickSeconds = OpenClickMicros = 0;
/* And now, do that requester. */
DoRequest(&OpenReqSupport);
/* Back, eh? Wasn't that easy? */
if (FlagIsSet(fileio->Flags, LOCK_GOTTEN))
{
UnLock(fileio->DOSLock);
ClearFlag(fileio->Flags, LOCK_GOTTEN);
}
CurrentDir(OpenSaveLock);
OpenReqFileIO = NULL;
/* Strip any excess leading and trailing blanks off the final name */
newtext = StripOuterSpace(&fileio->FileName[0], " ");
CopyString(&fileio->FileName[0], newtext);
if (OpenReqSupport.SelectedGadgetID != OPENGADGET_CANCEL)
return(TRUE);
return(FALSE);
}
/* *** BuildFileIOPathname() ************************************************
*
* NAME
* BuildFileIOPathname -- Build a file pathname using a FileIO struct
*
*
* SYNOPSIS
* BuildFileIOPathname(FileIOSupport, Buffer);
*
*
* FUNCTION
* Builds the text for a pathname using the FileName[], DrawerName[] and
* DiskName[] fields of the specified FileIOSupport structure
* after the support structure has been used in a successful call
* to GetFileIOName(). Writes the text into the Buffer.
*
*
* INPUTS
* FileIOSupport = the address of a FileIOSupport structure
* Buffer = address of the buffer to receive the file pathname
*
*
* RESULT
* None
*
*
* SEE ALSO
* GetFileIOName()
*/
VOID BuildFileIOPathname(fileio, buffer)
struct FileIOSupport *fileio;
UBYTE *buffer;
{
StripOuterSpace(&fileio->DiskName[0], " ");
StripOuterSpace(&fileio->DrawerName[0], " ");
StripOuterSpace(&fileio->FileName[0], " ");
CopyString(buffer, &fileio->DiskName[0]);
if (StringLength(&fileio->DrawerName[0]))
{
ConcatString(buffer, &fileio->DrawerName[0]);
ConcatString(buffer, "/");
}
ConcatString(buffer, &fileio->FileName[0]);
}
/* *** AddFileIOName() ******************************************************
*
* NAME
* AddFileIOName -- Add a file name to the names in a FileIOSupport
*
*
* SYNOPSIS
* AddFileIOName(FileIOSupport, FileName);
*
*
* FUNCTION
* This routine adds a file name to the list of file names currently
* in the specified FileIOSupport structure. The next time the
* FileIOSupport structure is used for a call to GetFileIOName(), the
* new file name will apppear alphabetized in with the other file names.
*
* This routine will most often be used after a call to GetFileIOName()
* or some other routine where the user is allowed to specify the name
* of a file to be opened for output. If the file is opened
* successfully, this routine will make sure that the name of the file
* is in the FileIOSupport structure. This is important if the output
* file has been newly created; otherwise, without calling this
* routine, the next time the FileIOSupport structure is used the new
* file name would not appear even though the file exists. If the name
* is already in the list when you call AddFileIOName() then nothing
* happens. This allows you to call AddFileIOName() without worrying
* about duplicate name redundancy.
*
* Here's a typical sequence of events leading up to a call to
* AddFileIOName():
*
* First, get a FileIOSupport structure:
* fileio = GetFileIOSupport(...);
*
* When the user wants to write data, use GetFileIOName()
* to provide a convenient and consistent interface to
* the filesystem:
* goodfile = GetFileIOName(...);
*
* If the user has selected a name for output (in this example,
* goodfile will equal TRUE if the user selected a name), then
* open the file (possibly creating it) and then call
* AddFileIOName() to make sure the name is in the FileIOSupport
* structure's list:
* if (goodfile)
* {
* UBYTE filename[80];
*
* BuildFileIOPathname(fileio, &filename[0]);
* ... open filename, write it, close it ...
* if (filename opened successfully)
* AddFileIOName(fileio, &filename[0]);
* }
*
*
* INPUTS
* FileIOSupport = the address of a FileIOSupport structure
* FileName = the address of null-terminated text that is
* either a simple file name or a valid AmigaDOS pathname.
*
*
* RESULT
* None
*
*
* SEE ALSO
* GetFileIOName()
* GetFileIOSupport()
*/
VOID AddFileIOName(fileio, filename)
struct FileIOSupport *fileio;
UBYTE *filename;
{
SHORT index, i, length;
struct Remember *remember, *oldremember;
UBYTE *nextentry;
struct Remember *namekey;
/* Does the filename start with a volume name? If so, skip over it */
index = IndexString(filename, ":");
if (index >= 0) filename += index + 1;
/* Does the filename start with a directory name? If so, skip over it */
do
{
index = IndexString(filename, "/");
if (index >= 0) filename += index + 1;
}
while (index >= 0);
if (*filename == 0) return;
/* Here, filename points to what is presumed to be a valid file name.
* If it's found among the FileIOSupport's names, exit.
* If it's not found in the list, add it.
*
* The current file names are stored in the fileio's Remember list.
*/
remember = fileio->NameKey;
oldremember = NULL;
while (remember)
{
i = CompareUpperStrings(filename, remember->Memory);
if (i < 0) goto ADD_FILENAME;
if (i == 0) return;
oldremember = remember;
remember = remember->NextRemember;
}
ADD_FILENAME:
/* Name not on list, so add it now */
length = StringLength(filename);
namekey = NULL;
if (nextentry = AllocRemember(&namekey, length + 1 + 1, NULL))
{
CopyString(nextentry, filename);
*(nextentry + length + 1) = 0;
if (oldremember) oldremember->NextRemember = namekey;
else fileio->NameKey = namekey;
/* This assignment is valid whether or not remember is NULL */
namekey->NextRemember = remember;
fileio->NameCount++;
}
}
/* *** ReleaseFileIO() ******************************************************
*
* NAME
* ReleaseFileIO -- Release the FileIO structure and all local memory
*
*
* SYNOPSIS
* ReleaseFileIO(FileIO);
*
*
* FUNCTION
* Releases the FileIO structure by freeing all local memory attached
* to the structure and then freeing the structure itself.
*
*
* INPUTS
* FileIO = the address of a FileIO structure
*
*
* RESULT
* None
*
*
* SEE ALSO
* GetFileIOSupport()
*/
VOID ReleaseFileIO(fileio)
struct FileIOSupport *fileio;
{
if (fileio)
{
FreeRemember(&fileio->VolumeKey, TRUE);
FreeRemember(&fileio->NameKey, TRUE);
FreeMem(fileio, sizeof(struct FileIOSupport));
}
}