#include "cPreferencesFile.h" // =========================================================================== // cPreferencesFile.cpp Version 1.0 ©1998 Joakim Braun All rights reserved. // =========================================================================== // // CONTENTS: cPreferencesFile is a subclass of the Metrowerks PowerPlant LFile class // with functions to read and write resources in preferences files. // REQUIRES: PowerPlant LFile. // HOW TO USE: Instantiate a cPreferencesFile and use it for getting and setting resources: // // cPreferencesFile myPrefs("\pMy preferences", kPrefsFileCreator, kPrefsFileType, true); // Handle aHandle = myPrefs.GetPrefsResource(kMyResType, kMyResNum); // cPreferencesFile is free for any and all use. // Do not distribute modified source code under my name. // No support promised, no liability accepted. Provided "as is". // That said, I can be reached at braun@swipnet.se. // Latest version at http://home4.swipnet.se/~w-41308/ // Change history: // 1.0 September 11, 1998 First release // ----------------------------------------------------------------- // Ä Constructor // ----------------------------------------------------------------- // Try to locate preferences file. If it doesn't exist and inCreateMissingFile is true, create it. cPreferencesFile:: cPreferencesFile(Str255 inPrefsFileName, OSType inPrefsFileCreator, OSType inPrefsFileType, Boolean inCreateMissingFile){ if(MakeSelfFileSpec(inPrefsFileName) == fnfErr && inCreateMissingFile){ try{ CreateNewFile(inPrefsFileCreator, inPrefsFileType); } catch(...){ // Don't throw exceptions from constructors } } } // ----------------------------------------------------------------- // Ä MakeSelfFileSpec() // ----------------------------------------------------------------- // Try to create FSSpec for preferences file, store it in mMacFileSpec OSErr cPreferencesFile::MakeSelfFileSpec(Str255 inPrefsFileName){ long prefsDirID = 0; short prefsVRefNum = 0; OSErr result = ::FindFolder(kOnSystemDisk, kPreferencesFolderType, true, &prefsVRefNum, &prefsDirID); if (result != noErr) return result; return ::FSMakeFSSpec(prefsVRefNum, prefsDirID, inPrefsFileName, &mMacFileSpec); } // ----------------------------------------------------------------- // Ä GetPrefsResource() // ----------------------------------------------------------------- // Try to get handle of a given resource. Throw exception on error or NULL handle if inThrowIfError is true. // Otherwise, return handle, whether it's NULL or not. Handle cPreferencesFile:: GetPrefsResource(OSType inResType, ResIDT inResNum, Boolean inThrowIfError){ Int16 currResFile = ::CurResFile(); Int16 resForkID = -1; Handle result = NULL; try{ resForkID = OpenResourceFork(fsRdPerm); result = ::Get1Resource(inResType, inResNum); ThrowIfResError_(); ThrowIfNil_(result); ::DetachResource(result); CloseResourceFork(); ::UseResFile(currResFile); } catch(...){ CloseResourceFork(); ::UseResFile(currResFile); if(inThrowIfError) throw; } return result; } // ----------------------------------------------------------------- // Ä SetPrefsResource() // ----------------------------------------------------------------- // Set resource data of a given resource to data provided. // Throw exception on error if inThrowIfError is true, // otherwise return error code. // inResDataH will be turned into a resource handle by this operation. // If inAdoptHandle is true, deletes inResDataH. OSErr cPreferencesFile:: SetPrefsResource(Handle inResDataH, OSType inResType, ResIDT inResNum, Str255 inResName, Boolean inAdoptHandle, Boolean inThrowIfError){ OSErr result = noErr; Handle resHandle = NULL; Int16 currResFile = ::CurResFile(); Int16 resForkID = -1; try{ resForkID = OpenResourceFork(fsRdWrPerm); // Delete existing resource resHandle = ::Get1Resource(inResType, inResNum); if(resHandle){ ::RemoveResource(resHandle); ::DisposeHandle(resHandle); } resHandle = inResDataH; // Add new resource ::AddResource(resHandle, inResType, inResNum, inResName); result = ::ResError(); ThrowIfOSErr_(result); ::UpdateResFile(resForkID); result = ::ResError(); ThrowIfOSErr_(result); if(inAdoptHandle) ::ReleaseResource(resHandle); CloseResourceFork(); ::UseResFile(currResFile); } catch(...){ CloseResourceFork(); ::UseResFile(currResFile); if(inThrowIfError) throw; } return result; } // ----------------------------------------------------------------- // Ä SetPrefsResource() // ----------------------------------------------------------------- // Same as above, except takes pointer and Int32 instead of handle OSErr cPreferencesFile:: SetPrefsResource(void* inData, Int32 inDataLength, OSType inResType, ResIDT inResNum, Str255 inResName, Boolean inAdoptHandle, Boolean inThrowIfError){ Handle resHandle = ::NewHandle(inDataLength); OSErr result = noErr; if(resHandle){ ::BlockMove(inData, &**resHandle, inDataLength); result = SetPrefsResource(resHandle, inResType, inResNum, inResName, true, inThrowIfError); } else result = memFullErr; if(inThrowIfError) ThrowIfOSErr_(result); return result; }