home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1997 January / macformat46.iso / Shareware Plus / Developers / Library / Grant's CGI Framework / Grant's CGI Framework / grantscgi / Util / PrefUtil.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-20  |  10.4 KB  |  452 lines

  1. /*****
  2.  *
  3.  *    PrefUtil.c
  4.  *
  5.  *    This is a support file for "Grant's CGI Framework".
  6.  *    Please see the license agreement that accompanies the distribution package
  7.  *    for licensing details.
  8.  *
  9.  *    Copyright ©1996 by Grant Neufeld
  10.  *    grant@acm.com
  11.  *    http://arpp.carleton.ca/cgi/framework/
  12.  *
  13.  *****/
  14.  
  15. #include "MyConfiguration.h"
  16. #if kCompileWithPreferences
  17.  
  18. #include "constants.h"
  19. #include "globals.h"
  20.  
  21. #include "CGI.h"
  22. #include "DebugUtil.h"
  23. #include "FileUtil.h"
  24. #include "MemoryUtil.h"
  25. #include "ProcessUtil.h"
  26.  
  27. #include "PrefUtil.h"
  28.  
  29.  
  30. /***  LOCAL VARIABLES  ***/
  31.  
  32. static FSSpec    vPrefFSSpec;
  33. static SInt16    vPrefFileRef;    /* reference of the open preference file */
  34. static SInt16    vSavedFileRef;
  35.  
  36. static UInt16    vPrefBusyTotal;    /* total # of resources used from the prefs file */    
  37.  
  38.  
  39. /***  LOCAL PROTOTYPES  ***/
  40.  
  41. static OSErr    prefFileCreate    ( void );
  42. static OSErr    prefFileOpen    ( Boolean );
  43. static OSErr    prefFileClose    ( void );
  44.  
  45.  
  46. /***  FUNCTIONS  ***/
  47.  
  48. /*  */
  49. void
  50. PrefStartup ( void )
  51. {
  52.     /* initialize module variables */
  53.     vPrefFSSpec.vRefNum = nil;
  54.     vPrefFSSpec.parID = nil;
  55.     (vPrefFSSpec.name)[0] = nil;
  56.     vPrefFileRef = nil;
  57.     vSavedFileRef = nil;
  58.     vPrefBusyTotal = nil;
  59. } /* PrefStartup */
  60.  
  61.  
  62. /** Preference Item Access **/
  63. #pragma mark -
  64.  
  65. /* when loading preference resources from CGI functions, you should try to
  66.     just get the data and release the resource very quickly (unless your
  67.     resources are purgable - which requires extra caution on your part).
  68.     Otherwise, you may end up clogging the host application's memory when
  69.     running as a plugin */
  70.  
  71. /* Get the resource from the preferences file.
  72.     If the prefs file doesn't exist or doesn't contain the resource,
  73.     the resource will be accessed from the application fork.
  74.     If the app fork doesn't contain the resource, returns NULL.
  75.     You must use PrefItemRelease to release the resource when done with it. */
  76. p_export
  77. Handle
  78. PrefItemGet ( short theResID, ResType theResType )
  79. {
  80.     OSErr    theErr;
  81.     Handle    thePref;
  82.     
  83.     theErr = prefFileOpen ( false );
  84.     
  85.     thePref = GetResource ( theResType, theResID );
  86.     if ( (thePref != NULL) && (theErr == noErr) )
  87.     {
  88.         /* since we presumably got the resource from the prefs file,
  89.             increment the counter so that we can track how many rsrcs have
  90.             been pulled from the file so we can know whether it should be
  91.             closed or not at a later point */
  92.         vPrefBusyTotal++;
  93.     }
  94.     
  95.     return thePref;
  96. } /* PrefItemGet */
  97.  
  98.  
  99. /* Releases a resource that was accessed via PrefItemGet. */
  100. p_export
  101. void
  102. PrefItemRelease ( Handle thePref )
  103. {
  104.     my_assert ( thePref != NULL, "\pPreferenceReleaseRsrc: thePref is NULL" );
  105.     
  106.     if ( thePref != NULL )
  107.     {
  108.         ReleaseResource    ( thePref );
  109.         
  110.         if ( vPrefFileRef > nil )
  111.         {
  112.             my_assert ( vPrefBusyTotal > nil, "\pPrefItemRelease: vPrefBusyTotal is too small" );
  113.             
  114.             vPrefBusyTotal--;
  115.         }
  116.     }
  117.     
  118.     if ( (vPrefBusyTotal == nil) && (vPrefFileRef > nil) )
  119.     {
  120.         prefFileClose ();
  121.     }
  122. } /* PrefItemRelease */
  123.  
  124.  
  125. /* Save the data as the specified resource in the preferences file.
  126.     If the file doesn't exist yet, create it.
  127.     theName is a Pascal format string - can be a NULL ptr. */
  128. p_export
  129. OSErr
  130. PrefItemSave ( short theResID, ResType theResType, void *theData, short theSize, StringPtr theName )
  131. {
  132.     OSErr        theErr;
  133.     Handle        theOldResource;
  134.     Handle        prefHandle;
  135.     
  136.     my_assert ( theData != NULL, "\pPrefItemSave: theData is NULL" );
  137.     my_assert ( theSize > nil, "\pPrefItemSave: theSize is < nil" );
  138.     
  139.     theErr = prefFileOpen ( true );
  140.     if ( theErr == noErr )
  141.     {
  142.         /* prefs file is open and writable */
  143.         
  144.         /* delete existing resource in prefs file, if there is one */
  145.         theOldResource = Get1Resource ( theResType, theResID );
  146.         if ( theOldResource != NULL )
  147.         {
  148.             if ( theName == NULL )
  149.             {
  150.                 /* caller didn't supply a name, so use the old one */
  151.                 //•••
  152.             }
  153.             
  154.             RemoveResource ( theOldResource );
  155.             DisposeHandle  ( theOldResource );
  156.         }
  157.         
  158.         prefHandle = MemoryNewHandle ( theSize, &theErr );
  159.         if ( prefHandle != NULL )
  160.         {
  161.             /* copy the data into the new handle */
  162.             HLock        ( prefHandle );
  163.             BlockMove    ( theData, *prefHandle, theSize );
  164.             HUnlock        ( prefHandle );
  165.             
  166.             AddResource        ( prefHandle, theResType, theResID, theName );
  167.             UpdateResFile    ( CurResFile() );
  168.             ReleaseResource ( prefHandle );
  169.         }
  170.         
  171.         prefFileClose ();
  172.     }
  173.     
  174.     return theErr;
  175. } /* PrefItemSave */
  176.  
  177. /* same as PrefItemSave except uses CGI memory calls
  178.     Use this when calling from a CGI function. */
  179. p_export
  180. OSErr
  181. PrefItemCGISave ( CGIHdl theCGIHdl, short theResID, ResType theResType, void *theData, short theSize, StringPtr theName )
  182. {
  183. #if !(kCompilingForWSAPI || kCompileWithAssertions)
  184. #pragma unused(theCGIHdl)
  185. #endif
  186.     
  187.     OSErr        theErr;
  188.     Handle        theOldResource;
  189.     Handle        prefHandle;
  190.     
  191.     my_assert ( theCGIHdl != NULL, "\pPrefItemCGISave: theCGIHdl is NULL" );
  192.     my_assert ( theData != NULL, "\pPrefItemCGISave: theData is NULL" );
  193.     my_assert ( theSize > nil, "\pPrefItemCGISave: theSize is < nil" );
  194.     
  195.     theErr = prefFileOpen ( true );
  196.     if ( theErr != noErr )
  197.     {
  198.         /* prefs file is open and writable */
  199.         
  200.         /* delete existing resource in prefs file, if there is one */
  201.         theOldResource = Get1Resource ( theResType, theResID );
  202.         if ( theOldResource != NULL )
  203.         {
  204.             if ( theName == NULL )
  205.             {
  206.                 /* caller didn't supply a name, so use the old one */
  207.                 //•••
  208.             }
  209.             
  210.             RemoveResource ( theOldResource );
  211.             DisposeHandle  ( theOldResource );
  212.         }
  213.         
  214.         prefHandle = CGINewHandle ( theCGIHdl, theSize, &theErr );
  215.         if ( prefHandle != NULL )
  216.         {
  217.             /* copy the data into the new handle */
  218.             HLock        ( prefHandle );
  219.             BlockMove    ( theData, *prefHandle, theSize );
  220.             HUnlock        ( prefHandle );
  221.             
  222.             AddResource        ( prefHandle, theResType, theResID, theName );
  223.             UpdateResFile    ( CurResFile() );
  224.             ReleaseResource ( prefHandle );
  225.         }
  226.         
  227.         prefFileClose ();
  228.     }
  229.     
  230.     return theErr;
  231. } /* PrefItemCGISave */
  232.  
  233.  
  234. #pragma mark -
  235.  
  236. /* Open the preferences file and set it as the current resource file. */
  237. static OSErr
  238. prefFileOpen ( Boolean createIfDoesntExist )
  239. {
  240.     #if kCompileWithPreferencesFile
  241.     
  242.     OSErr        theErr;
  243. //    SInt16        prefVolRef;
  244. //    SInt32        prefDir;
  245.     Str255        prefFilename;
  246.     Boolean        isFolder;        /* used for Finder alias resolving */
  247.     Boolean        wasAliased;        /* used for Finder alias resolving */
  248.     
  249.     if ( vPrefFileRef > nil )
  250.     {
  251.         return noErr;
  252.     }
  253.     
  254.     if ( (vPrefFSSpec.name)[0] == '\0' )
  255.     {
  256.         /* fsspec is empty, so the file hasn't been previously located - find it */
  257.         
  258.         /* we locate the preferences file in the same folder as the application */
  259.         
  260.         /* get the name of the preferences file */
  261.         GetIndString ( prefFilename, krFilenamesStrs, kriFilenamePref );
  262.         
  263.         /* try to make the FSSpec */
  264.         theErr = FSMakeFSSpec ( gProcessFSSpec.vRefNum, gProcessFSSpec.parID, prefFilename, &vPrefFSSpec );
  265.         if ( (theErr == fnfErr) && createIfDoesntExist )
  266.         {
  267.             /* File Not Found: need to create the file */
  268.             theErr = prefFileCreate ();
  269.         }
  270.         else if ( theErr == noErr )
  271.         {
  272.             /* we've located the file */
  273.             /* handle any Finder aliasing without user prompts if on an unmounted
  274.                 network volume */
  275.             theErr = ResolveAliasFileMountOption ( &vPrefFSSpec, true, &isFolder, &wasAliased, false );
  276.             if ( isFolder )
  277.             {
  278.                 theErr = true;    //• need error to indicate folder found when file expected
  279.             }
  280.         }
  281.         
  282.         if ( theErr != noErr )
  283.         {
  284.             /* clear out the fsspec since we failed to set it correctly */
  285.             (vPrefFSSpec.name)[0] = nil;
  286.             
  287.             return theErr;
  288.         }
  289.     }
  290.     
  291.     vSavedFileRef = CurResFile ();
  292.     
  293.     /* Try opening the Preferences file */
  294.     vPrefFileRef = FSpOpenResFile ( &vPrefFSSpec, fsRdWrPerm );
  295.     if ( vPrefFileRef == -1 )
  296.     {
  297.         /* the file wasn't opened */
  298.         theErr = ResError ();
  299.         vPrefFileRef = nil;
  300.     }
  301.     else
  302.     {
  303.         /* if the prefs file is open now, use it */
  304.         UseResFile ( vPrefFileRef );
  305.         theErr = noErr;
  306.     }
  307.     
  308.     return theErr;
  309.     
  310.     #else
  311.     #pragma unused(createIfDoesntExist)
  312.     
  313.     return noErr;
  314.     
  315.     #endif /* kCompileWithPreferencesFile */
  316. } /* prefFileOpen */
  317.  
  318.  
  319. /* Close the preferences file. */
  320. static OSErr
  321. prefFileClose ( void )
  322. {
  323.     #if kCompileWithPreferencesFile
  324.     if ( (vPrefBusyTotal == nil) && (vPrefFileRef != nil) )
  325.     {
  326.         CloseResFile ( vPrefFileRef );
  327.         UseResFile     ( vSavedFileRef );
  328.         
  329.         vPrefFileRef  = nil;
  330.     }
  331.     #endif
  332.     
  333.     return noErr;
  334. } /* prefFileClose */
  335.  
  336.  
  337. /* Create the preferences file. */
  338. static OSErr
  339. prefFileCreate ( void )
  340. {
  341.     OSErr    theErr;
  342.     
  343.     my_assert ( (vPrefFSSpec.name)[0] != '\0', "\pprefFileCreate: vPrefFSSpec is incomplete" );
  344.     
  345.     FSpCreateResFile ( &vPrefFSSpec, kMyCreatorType, kTypePref, smSystemScript );
  346.     theErr = ResError ();
  347.     
  348.     //••• add copying of default resources here
  349.     
  350.     return theErr;
  351. } /* prefFileCreate */
  352.  
  353.  
  354. /**  INDIVIDUAL PREFERENCES  **/
  355. #pragma mark -
  356.  
  357. /*  */
  358. #if 0
  359. void
  360. PrefSaveCurrentSettings ( void )
  361. {
  362.     
  363. } /* PrefSaveCurrentSettings */
  364. #endif
  365.  
  366.  
  367. /*  */
  368. void
  369. PrefSaveSleepTicks ( UInt32 theSleepTicks )
  370. {
  371.     OSErr    theErr;
  372.     UInt32    oldSleepTicks;
  373.     
  374.     oldSleepTicks = ProcessSleepGetDefault ();
  375.     if ( theSleepTicks != oldSleepTicks )
  376.     {
  377.         theErr = PrefItemSave ( krPrefSleepTicks, kPrefResType, &theSleepTicks, sizeof(UInt32), "\pSleepTicks" );
  378.     }
  379. } /* PrefSaveSleepTicks */
  380.  
  381. /*  */
  382. void
  383. PrefSaveSleepTicksBusy ( UInt32 theSleepTicks )
  384. {
  385.     OSErr    theErr;
  386.     UInt32    oldSleepTicks;
  387.     
  388.     oldSleepTicks = ProcessSleepGetBusy ();
  389.     if ( theSleepTicks != oldSleepTicks )
  390.     {
  391.         theErr = PrefItemSave ( krPrefSleepTicksBusy, kPrefResType, &theSleepTicks, sizeof(UInt32), "\pSleepTicksWhenBusy" );
  392.     }
  393. } /* PrefSaveSleepTicksBusy */
  394.  
  395. /*  */
  396. void
  397. PrefSaveDoIdleQuit ( SInt16 theBoolean )
  398. {
  399.     #if kCompileWithQuitOnLongIdle
  400.     
  401.     OSErr    theErr;
  402.     
  403.     if ( (gDoIdleQuit && !theBoolean) || (!gDoIdleQuit && theBoolean) )
  404.     {
  405.         theErr = PrefItemSave ( krPrefDoIdleQuit, kPrefResType, &theBoolean, sizeof(SInt16), "\pDoIdleQuit" );
  406.     }
  407.     
  408.     #else
  409.     #pragma unused(theBoolean)
  410.     #endif /* kCompileWithQuitOnLongIdle */
  411. } /* PrefSaveDoIdleQuit */
  412.  
  413. /*  */
  414. void
  415. PrefSaveDoIdleQuitOnOpenApp ( SInt16 theBoolean )
  416. {
  417.     #if kCompileWithQuitOnLongIdle
  418.     
  419.     OSErr    theErr;
  420.     
  421.     if ( (gDoIdleQuitOnOpenApp && !theBoolean) || (!gDoIdleQuitOnOpenApp && theBoolean) )
  422.     {
  423.         theErr = PrefItemSave ( krPrefDoIdleQuitOnOpenApp, kPrefResType, &theBoolean, sizeof(SInt16), "\pDoIdleQuitOnOpenApp" );
  424.     }
  425.     
  426.     #else
  427.     #pragma unused(theBoolean)
  428.     #endif /* kCompileWithQuitOnLongIdle */
  429. } /* PrefSaveDoIdleQuitOnOpenApp */
  430.  
  431. /*  */
  432. void
  433. PrefSaveIdleTimeToQuit ( UInt32 idleTime )
  434. {
  435.     #if kCompileWithQuitOnLongIdle
  436.     
  437.     OSErr    theErr;
  438.     
  439.     if ( idleTime != gIdleTimeToQuit )
  440.     {
  441.         theErr = PrefItemSave ( krPrefIdleTimeToQuit, kPrefResType, &idleTime, sizeof(UInt32), "\pIdleTimeToQuit" );
  442.     }
  443.     
  444.     #else
  445.     #pragma unused(idleTime)
  446.     #endif /* kCompileWithQuitOnLongIdle */
  447. } /* PrefSaveIdleTimeToQuit */
  448.  
  449.  
  450. #endif /* kCompileWithPreferences */
  451. /*****  EOF  *****/
  452.