home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C ++ / Frameworks / MacZoop 1.6.5 / More Classes / File Classes / ZResourceFile.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-21  |  12.3 KB  |  536 lines  |  [TEXT/CWIE]

  1. /*************************************************************************************************
  2. *
  3. *
  4. *            ObjectMacZapp        -- a standard Mac OOP application template
  5. *
  6. *
  7. *
  8. *            ZResourceFile.cpp    -- a generic resource file/manager object
  9. *
  10. *
  11. *
  12. *
  13. *
  14. *            © 1997, Graham Cox
  15. *
  16. *
  17. *
  18. *
  19. *************************************************************************************************/
  20.  
  21. #include    "ZResourceFile.h"
  22. #include    "MacZoop.h"
  23.  
  24. static FSSpec    gDummySpec = { 0, 0, "\p" };
  25.  
  26. /*-----------------------------***  CONSTRUCTORS  ***----------------------------------*/
  27.  
  28. ZResourceFile::ZResourceFile( const FSSpec& aSpec )
  29.     : ZFile( aSpec )
  30. {
  31. }
  32.  
  33.  
  34. ZResourceFile::ZResourceFile( Str255 fName )
  35.     : ZFile( fName )
  36. {
  37. }
  38.  
  39.  
  40. ZResourceFile::ZResourceFile( const short aRefNum )
  41.     : ZFile( gDummySpec )
  42. {
  43.     // if the file was opened externally (for example, applications are opened
  44.     // by the process manager) you can construct this object with this constructor
  45.     // to obtain a nice object interface to the resources anyway.
  46.     
  47.     resRefNum = aRefNum;
  48. }
  49.  
  50.  
  51. /*-----------------------------***  READRESOURCE  ***----------------------------------*/
  52. /*
  53. get a resource with the type and ID passed, optionally detaching it
  54. ---------------------------------------------------------------------------------------*/
  55.  
  56. Handle        ZResourceFile::ReadResource( const ResType aType, const short resID, const Boolean detachIt)
  57. {
  58.     Handle    h = NULL;
  59.     short    saveRes;
  60.     
  61.     FailOSErr((resRefNum == _NOT_OPEN)? resFNotFound : noErr );
  62.     SetResFork( &saveRes );
  63.     
  64.     try
  65.     {
  66.         h = Get1Resource( aType, resID );
  67.         FailOSErr( ResError());
  68.         
  69.         if ( detachIt )
  70.             DetachResource( h );
  71.     }
  72.     catch( OSErr err )
  73.     {
  74.         UseResFile( saveRes );
  75.         
  76.         throw err;
  77.     }
  78.     
  79.     UseResFile( saveRes );
  80.     
  81.     return h;
  82. }
  83.  
  84.  
  85. /*-----------------------------***  READRESOURCE  ***----------------------------------*/
  86. /*
  87. get an indexed resource with the type and index passed, optionally detaching it
  88. ---------------------------------------------------------------------------------------*/
  89.  
  90. Handle        ZResourceFile::ReadResource( const short index, const ResType aType, const Boolean detachIt)
  91. {
  92.     Handle    h = NULL;
  93.     short    saveRes;
  94.     
  95.     FailOSErr((resRefNum == _NOT_OPEN)? resFNotFound : noErr );
  96.     SetResFork( &saveRes );
  97.     
  98.     try
  99.     {
  100.         h = Get1IndResource( aType, index );
  101.         FailOSErr( ResError());
  102.         
  103.         if ( detachIt )
  104.             DetachResource( h );
  105.     }
  106.     catch( OSErr err )
  107.     {
  108.         UseResFile( saveRes );
  109.         
  110.         throw err;
  111.     }
  112.     
  113.     UseResFile( saveRes );
  114.     
  115.     return h;
  116. }
  117.  
  118.  
  119. /*-----------------------------***  READRESOURCE  ***----------------------------------*/
  120. /*
  121. get a resource with the type and name passed, optionally detaching it
  122. ---------------------------------------------------------------------------------------*/
  123.  
  124. Handle        ZResourceFile::ReadResource( const ResType aType, Str255 resName, const Boolean detachIt)
  125. {
  126.     Handle    h = NULL;
  127.     short    saveRes;
  128.     
  129.     FailOSErr((resRefNum == _NOT_OPEN)? resFNotFound : noErr );
  130.     SetResFork( &saveRes );
  131.     
  132.     try
  133.     {
  134.         h = Get1NamedResource( aType, resName );
  135.         FailOSErr( ResError());
  136.         
  137.         if ( detachIt )
  138.             DetachResource( h );
  139.     }
  140.     catch( OSErr err )
  141.     {
  142.         UseResFile( saveRes );
  143.         
  144.         throw err;
  145.     }
  146.     
  147.     UseResFile( saveRes );
  148.     
  149.     return h;
  150. }
  151.  
  152.  
  153. /*-----------------------------***  OWNSRESOURCE  ***----------------------------------*/
  154. /*
  155. does this resource handle belong to this file? (FALSE if not a resource handle)
  156. ---------------------------------------------------------------------------------------*/
  157.  
  158. Boolean        ZResourceFile::OwnsResource( Handle aResHandle )
  159. {
  160.     short    hf;
  161.     
  162.     FailOSErr((aResHandle == NULL)? paramErr : noErr );
  163.     hf = HomeResFile( aResHandle );
  164.     
  165.     if ((hf == -1) ||
  166.         (hf != resRefNum))
  167.         return FALSE;
  168.     else
  169.         return TRUE;
  170. }
  171.  
  172.  
  173. /*------------------------------***  HASRESOURCE  ***----------------------------------*/
  174. /*
  175. does this file contain a resource of the type and ID passed?
  176. ---------------------------------------------------------------------------------------*/
  177.  
  178. Boolean        ZResourceFile::HasResource( const ResType aType, const short resID )
  179. {
  180.     Handle    h;
  181.     Boolean    result = FALSE;
  182.     
  183.     SetResLoad( FALSE );
  184.     
  185.     try
  186.     {
  187.         h = GetResource( aType, resID );
  188.         
  189.         if( h )
  190.             result = TRUE;
  191.     }
  192.     catch( OSErr err )
  193.     {
  194.         // do not throw this exception (return false instead)
  195.     }
  196.     
  197.     SetResLoad( TRUE );
  198.     
  199.     return result;
  200. }
  201.  
  202.  
  203. /*-------------------------------***  HASRESTYPE  ***----------------------------------*/
  204. /*
  205. does the file contain any resources of the type passed?
  206. ---------------------------------------------------------------------------------------*/
  207.  
  208. Boolean        ZResourceFile::HasResType( const ResType aType )
  209. {
  210.     Boolean        result = FALSE;
  211.     
  212.     try
  213.     {
  214.         result = ( CountResources( aType ) > 0);
  215.     }
  216.     catch( OSErr err )
  217.     {
  218.         // this exception is not thrown
  219.     }
  220.     
  221.     return result;
  222. }
  223.  
  224.  
  225. /*----------------------------***  TOTALRESOURCES  ***---------------------------------*/
  226. /*
  227. how many resources are there altogether in this file?
  228. ---------------------------------------------------------------------------------------*/
  229.  
  230. short        ZResourceFile::TotalResources()
  231. {
  232.     FailOSErr(( resRefNum == _NOT_OPEN )? resFNotFound : noErr );
  233.     
  234.     short    saveRes, num;
  235.     
  236.     SetResFork( &saveRes );
  237.     
  238.     num = Count1Types();
  239.     UseResFile( saveRes );
  240.     
  241.     return num;
  242. }
  243.  
  244.  
  245. /*----------------------------***  COUNTRESOURCES  ***---------------------------------*/
  246. /*
  247. how many resources of a given type are there in this file?
  248. ---------------------------------------------------------------------------------------*/
  249.  
  250. short        ZResourceFile::CountResources( const ResType aType )
  251. {
  252.     FailOSErr(( resRefNum == _NOT_OPEN )? resFNotFound : noErr );
  253.     
  254.     short    saveRes, num;
  255.     
  256.     SetResFork( &saveRes );
  257.     
  258.     num = Count1Resources( aType );
  259.     UseResFile( saveRes );
  260.     
  261.     return num;
  262. }
  263.  
  264.  
  265. /*----------------------------***  GETRFATTRIBUTES  ***--------------------------------*/
  266. /*
  267. return the file attributes for this resource file
  268. ---------------------------------------------------------------------------------------*/
  269.  
  270. short        ZResourceFile::GetRFAttributes()
  271. {
  272.     FailOSErr(( resRefNum == _NOT_OPEN )? resFNotFound : noErr );
  273.     
  274.     return GetResFileAttrs( resRefNum );
  275. }
  276.  
  277.  
  278. /*----------------------------***  GETRESOURCEINFO  ***--------------------------------*/
  279. /*
  280. get information about a resource (including the name)
  281. ---------------------------------------------------------------------------------------*/
  282.  
  283. void        ZResourceFile::GetResourceInfo(  Handle aResHandle, ResType* itsType, short* itsID, Str255 itsName )
  284. {
  285.     FailOSErr(( resRefNum == _NOT_OPEN )? resFNotFound : noErr );
  286.     
  287.     GetResInfo( aResHandle, itsID, itsType, itsName );
  288. }
  289.  
  290.  
  291. /*----------------------------***  GETRESOURCEINFO  ***--------------------------------*/
  292. /*
  293. get information about a resource (not including the name)
  294. ---------------------------------------------------------------------------------------*/
  295.  
  296. void        ZResourceFile::GetResourceInfo(  Handle aResHandle, ResType* itsType, short* itsID )
  297. {
  298.     FailOSErr(( resRefNum == _NOT_OPEN )? resFNotFound : noErr );
  299.     
  300.     Str255    itsName;
  301.     
  302.     GetResInfo( aResHandle, itsID, itsType, itsName );
  303. }
  304.  
  305.  
  306. /*-----------------------------***  WRITERESOURCE  ***---------------------------------*/
  307. /*
  308. add this handle to the resource file. If already part of this file, it is simply
  309. marked as modified and a subsequent flush or close will actually write it.
  310. ---------------------------------------------------------------------------------------*/
  311.  
  312. void        ZResourceFile::WriteResource( Handle aResHandle, const ResType aType, const short resID )
  313. {
  314.     FailOSErr(( resRefNum == _NOT_OPEN )? resFNotFound : noErr );
  315.     
  316.     if ( OwnsResource( aResHandle ))
  317.         ResourceModified( aResHandle );
  318.     else
  319.     {
  320.         // we don't already own this resource, so we need to add a new one, or
  321.         // perhaps modify an existing one if it's there already.
  322.         
  323.         short    saveRes;
  324.         
  325.         SetResFork( &saveRes );
  326.         
  327.         try
  328.         {
  329.             if ( HasResource( aType, resID ))
  330.             {
  331.                 // does the type and ID already exist? If so we should modify that one
  332.                 // rather than add a new one
  333.         
  334.                 Handle    h = GetResource( aType, resID );
  335.                 long    length;    
  336.                 
  337.                 SetHandleSize( h, length = GetHandleSize( aResHandle ));
  338.                 FailOSErr( MemError());
  339.                 
  340.                 // copy the handle to the resource handle
  341.                 
  342.                 BlockMoveData( *aResHandle, *h, length );
  343.                 ChangedResource( h );
  344.             }
  345.             else
  346.                 AddResource( aResHandle, aType, resID, "\p" );
  347.                 
  348.             FailOSErr( ResError());
  349.         }
  350.         catch( OSErr err )
  351.         {
  352.             UseResFile( saveRes );
  353.             
  354.             throw err;
  355.         }
  356.         
  357.         UseResFile( saveRes );
  358.     }
  359. }
  360.  
  361.  
  362. /*-----------------------------***  WRITERESOURCE  ***---------------------------------*/
  363. /*
  364. add this data to the resource file. This makes a new handle, or if the type and ID
  365. already exists, the new data replaces the old.
  366. ---------------------------------------------------------------------------------------*/
  367.  
  368. void        ZResourceFile::WriteResource( Ptr data, const long length, const ResType aType, const short resID )
  369. {
  370.     FailOSErr(( resRefNum == _NOT_OPEN )? resFNotFound : noErr );
  371.     FailOSErr(( length < 0 )? paramErr : noErr );
  372.     FailOSErr(( data == NULL )? paramErr : noErr );
  373.     
  374.     // is there already a resource of the type indicated?
  375.     
  376.     short    saveRes;
  377.     Handle    h;
  378.     
  379.     SetResFork( &saveRes );
  380.     
  381.     try
  382.     {
  383.         if ( HasResource( aType, resID ))
  384.         {
  385.             // yes, we already have such a resource type, so modify it
  386.             
  387.             h = GetResource( aType, resID );
  388.             
  389.             SetHandleSize( h, length );
  390.             FailOSErr( MemError());
  391.             
  392.             BlockMoveData( data, *h, length );
  393.             ChangedResource( h );    
  394.         }
  395.         else
  396.         {
  397.             // no, we don't have this type, so add it
  398.             
  399.             FailNIL( h = NewHandle( length ));
  400.         
  401.             BlockMoveData( data, *h, length );
  402.             AddResource( h, aType, resID, "\p" );
  403.             
  404.             FailOSErr( ResError());
  405.             
  406.             ReleaseResource( h );
  407.         }
  408.         
  409.         FailOSErr( ResError());
  410.     }
  411.     catch( OSErr err )
  412.     {
  413.         UseResFile( saveRes );
  414.         
  415.         throw err;
  416.     }
  417.     
  418.     UseResFile( saveRes );
  419. }
  420.  
  421.  
  422. /*-----------------------------***  DELETERESOURCE  ***--------------------------------*/
  423. /*
  424. remove the resource from the file. This disposes the handle.
  425. ---------------------------------------------------------------------------------------*/
  426.  
  427. void        ZResourceFile::DeleteResource( Handle aResHandle )
  428. {
  429.     FailOSErr(( resRefNum == _NOT_OPEN )? resFNotFound : noErr );
  430.     FailOSErr(( aResHandle == NULL )? paramErr : noErr );
  431.     
  432.     short    saveRes;
  433.     
  434.     SetResFork( &saveRes );
  435.     RemoveResource( aResHandle );
  436.     
  437.     try
  438.     {
  439.         FailOSErr( ResError());
  440.         DisposeHandle( aResHandle );
  441.     }
  442.     catch( OSErr err )
  443.     {
  444.         UseResFile( saveRes );
  445.         
  446.         throw err;
  447.     }
  448.     
  449.     UseResFile( saveRes );
  450. }
  451.  
  452. /*-----------------------------***  DELETERESOURCE  ***--------------------------------*/
  453. /*
  454. remove the resource of the given type and ID from the file.
  455. ---------------------------------------------------------------------------------------*/
  456.  
  457. void        ZResourceFile::DeleteResource( const ResType aType, const short resID )
  458. {
  459.     Handle        h;
  460.     
  461.     h = GetResource( aType, resID );
  462.     DeleteResource( h );
  463. }
  464.  
  465.  
  466. /*--------------------------------***  DELETEALL  ***----------------------------------*/
  467. /*
  468. remove all resources. This actually sets the length of the resource fork to zero
  469. ---------------------------------------------------------------------------------------*/
  470.  
  471. void        ZResourceFile::DeleteAll()
  472. {
  473.     // warning- use with extreme caution!
  474.     
  475.     Boolean        wasOpen = (resRefNum != _NOT_OPEN);
  476.     short        tempRef;
  477.     
  478.     if ( wasOpen )
  479.         CloseResFork();
  480.     
  481.     resRefNum = _NOT_OPEN;
  482.     
  483.     try
  484.     {    
  485.         // open the res fork as a fork without involving the resource manager,
  486.         // and set its length to zero.
  487.         
  488.         FailOSErr( FSpOpenRF( &itsSpec, fsCurPerm, &tempRef ));
  489.         FailOSErr( SetEOF( tempRef, 0 ));
  490.     }
  491.     catch( OSErr err )
  492.     {
  493.         FSClose( tempRef );
  494.         
  495.         throw err;
  496.     }
  497.     
  498.     FSClose( tempRef );
  499.     
  500.     // re-open the file with resource manager so that new map is built
  501.     
  502.     if ( wasOpen )
  503.         OpenResFork();
  504. }
  505.  
  506. /*-----------------------------***  RESOURCEMODIFIED  ***------------------------------*/
  507. /*
  508. the handle has been modified, mark it as such so the file is updated.
  509. ---------------------------------------------------------------------------------------*/
  510.  
  511. void        ZResourceFile::ResourceModified( Handle aResHandle )
  512. {
  513.     ChangedResource( aResHandle );
  514.     FailOSErr( ResError());
  515.     
  516.     // inhibit purging for this handle, so it gets written
  517.     // correctly later on.
  518.     
  519.     HNoPurge( aResHandle );
  520. }
  521.  
  522. /*----------------------------------***  FLUSH  ***------------------------------------*/
  523. /*
  524. write out all changed resources to the disk, leaving the file open. Close will do this
  525. as well, then close the file.
  526. ---------------------------------------------------------------------------------------*/
  527.  
  528. void        ZResourceFile::Flush()
  529. {
  530.     FailOSErr(( resRefNum == _NOT_OPEN )? resFNotFound : noErr );
  531.     
  532.     UpdateResFile( resRefNum );
  533. }
  534.  
  535.     
  536.