SMACsdec::~SMACsdec() { if(mDecoder != NULL) { #if USE_DIRECT_ADEC DirectAudioCodecClose(mDecoder); #else CloseComponent(mDecoder); #endif } delete[] mOutputBuffer; delete[] mFloatBuffer; #if TARGET_API_MAC_OSX delete mThreadStateMutex; mThreadStateMutex = NULL; #endif #if CaptureDataToFile if(mOutputFileRefNum != -1) { FSCloseFork(mOutputFileRefNum); } #endif }
static prMALError SDKQuietFile( imStdParms *stdParms, imFileRef *SDKfileRef, void *privateData) { // "Quiet File" really means close the file handle, but we're still // using it and might open it again, so hold on to any stored data // structures you don't want to re-create. // If file has not yet been closed if(SDKfileRef && *SDKfileRef != imInvalidHandleValue) { ImporterLocalRec8H ldataH = reinterpret_cast<ImporterLocalRec8H>(privateData); stdParms->piSuites->memFuncs->lockHandle(reinterpret_cast<char**>(ldataH)); ImporterLocalRec8Ptr localRecP = reinterpret_cast<ImporterLocalRec8Ptr>( *ldataH ); if(localRecP->vf) { int clear_err = ov_clear(localRecP->vf); assert(clear_err == OV_OK); delete localRecP->vf; localRecP->vf = NULL; } if(localRecP->opus) { op_free(localRecP->opus); localRecP->opus = NULL; } if(localRecP->flac) { localRecP->flac->finish(); delete localRecP->flac; localRecP->flac = NULL; } stdParms->piSuites->memFuncs->unlockHandle(reinterpret_cast<char**>(ldataH)); #ifdef PRWIN_ENV CloseHandle(*SDKfileRef); #else FSCloseFork( CAST_REFNUM(*SDKfileRef) ); #endif *SDKfileRef = imInvalidHandleValue; } return malNoError; }
static void do_close(rfobject *self) { if (self->isclosed ) return; (void)FSCloseFork(self->fRefNum); self->isclosed = 1; }
void LFA_Close ( LFA_FileRef file ) { if ( file == 0 ) return; // Can happen if LFA_Open throws an exception. long refNum = (long)file; // ! Use long to avoid size warnings for SInt16 cast. OSErr err = FSCloseFork ( refNum ); if ( err != noErr ) LFA_Throw ( "LFA_Close: FSCloseFork failure", kLFAErr_ExternalFailure ); } // LFA_Close
/******************************************************************** * CloseHandle ********************************************************************/ BOOL CloseHandle( HANDLE hFile ) /* handle to object */ { OSErr theErr; if ((hFile == NULL) || (hFile == INVALID_HANDLE_VALUE)) { return FALSE; } theErr = FSCloseFork((short)(long)hFile); SetLastError(theErr); return theErr != noErr; }
void XMLMacCarbonFile::close() { OSErr err = noErr; if (!mFileValid) ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotCloseFile); if (gHasHFSPlusAPIs) err = FSCloseFork(mFileRefNum); else err = FSClose(mFileRefNum); mFileValid = false; if (err != noErr) ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotCloseFile); }
void delete_AudioFilePlayer(AudioFilePlayer *afp) { if (afp != NULL) { afp->Disconnect(afp); if (afp->mAudioFileManager) { delete_AudioFileManager(afp->mAudioFileManager); afp->mAudioFileManager = 0; } if (afp->mForkRefNum) { FSCloseFork (afp->mForkRefNum); afp->mForkRefNum = 0; } SDL_free(afp); } }
static prMALError SDKQuietFile( imStdParms *stdParms, imFileRef *SDKfileRef, PrivateDataH privateData) { // If file has not yet been closed #ifdef PRWIN_ENV if (SDKfileRef && *SDKfileRef != imInvalidHandleValue) { CloseHandle (*SDKfileRef); *SDKfileRef = imInvalidHandleValue; } #else FSCloseFork (reinterpret_cast<intptr_t>(*SDKfileRef)); *SDKfileRef = imInvalidHandleValue; #endif return malNoError; }
OSErr SplitFileIfNeeded(FSRef * inFileReference,FSRef * inParentReference,FSCatalogInfo * inFileCatalogInfo,HFSUniStr255 * inFileName) { OSErr tErr; Boolean splitNeeded=FALSE; SInt16 tForkRefNum; UInt32 tResourceForkSize=0; static HFSUniStr255 sResourceForkName={0,{}}; Boolean hasResourceFork=FALSE; static UInt8 tPOSIXPath[PATH_MAX*2+1]; static UInt32 tPOSIXPathMaxLength=PATH_MAX*2; struct stat tFileStat; SInt16 tNewFileRefNum; if (sResourceForkName.length==0) { tErr=FSGetResourceForkName(&sResourceForkName); if (tErr!=noErr) { logerror("An error occurred when obtaining the ResourceFork name\n"); return -1; } } // 1. Check for the presence of a resource fork tErr=FSOpenFork(inFileReference,sResourceForkName.length,sResourceForkName.unicode,fsRdPerm,&tForkRefNum); if (tErr==noErr) { SInt64 tForkSize; // Get the size of the resource fork tErr=FSGetForkSize(tForkRefNum,&tForkSize); if (tErr!=noErr) { logerror("An error occurred on getting the resource fork size of a file or director\n"); FSCloseFork(tForkRefNum); return -1; } if (tForkSize>0xFFFFFFFF) { FSCloseFork(tForkRefNum); // AppleDouble File format does not support forks bigger than 2GB logerror("AppleDouble file format does not support forks bigger than 2 GB\n"); return -1; } tResourceForkSize=tForkSize; if (tForkSize>0) { hasResourceFork=TRUE; splitNeeded=TRUE; } else { FSCloseFork(tForkRefNum); } } else { switch(tErr) { case errFSForkNotFound: case eofErr: // No resource Fork tErr=noErr; break; default: logerror("Unable to open fork\n"); return -1; break; } } // 2. Check for the presence of FinderInfo or ExtFinderInfo if (splitNeeded==FALSE) { UInt32 * tUnsignedInt32Ptr; int i; // 1. We need to save the Folder(Ext) Info in the ._ file if there are any folder/finder or extend folder/finder info tUnsignedInt32Ptr= (UInt32 *) inFileCatalogInfo->finderInfo; for(i=0;i<4;i++) { if (tUnsignedInt32Ptr[i]!=0) { // We need to create a ._file splitNeeded=TRUE; break; } } if (splitNeeded==TRUE) // 01/02/07: Symbolic link looks like this { UInt32 tSymbolicLink; tSymbolicLink='s'; tSymbolicLink='l'+(tSymbolicLink<<8); tSymbolicLink='n'+(tSymbolicLink<<8); tSymbolicLink='k'+(tSymbolicLink<<8); if (tUnsignedInt32Ptr[0]==tSymbolicLink) { splitNeeded=FALSE; } } else { tUnsignedInt32Ptr= (UInt32 *) inFileCatalogInfo->extFinderInfo; for(i=0;i<4;i++) { if (tUnsignedInt32Ptr[i]!=0) { // We need to create a ._file splitNeeded=TRUE; break; } } } } // 3. Split if needed if (splitNeeded==TRUE) { FSRef tNewFileReference; HFSUniStr255 tNewFileName; // Get the absolute Posix Path Name tErr=FSRefMakePath(inFileReference,tPOSIXPath,tPOSIXPathMaxLength); if (tErr==noErr) { if (lstat((char *) tPOSIXPath,&tFileStat)==-1) { switch(errno) { case ENOENT: // A COMPLETER break; default: // A COMPLETER break; } tErr=-1; goto byebye; } } else { logerror("An error occurred when trying to get the absolute path of a file or directory\n"); tErr=-1; goto byebye; } if (gVerboseMode==TRUE) { printf(" splitting %s...\n",tPOSIXPath); } // Check that we do not explode the current limit for file names if (inFileName->length>gMaxFileNameLength) { // We do not have enough space to add the ._ prefix // The file name is too long // Write the error logerror("File name is too long. The maximum length allowed is %ld characters\n",gMaxFileNameLength+2); return -1; } tNewFileName.length=inFileName->length+2; tNewFileName.unicode[0]='.'; tNewFileName.unicode[1]='_'; BlockMoveData(inFileName->unicode,tNewFileName.unicode+2,inFileName->length*sizeof(UniChar)); // We need to create a ._file tryagain: tErr=FSCreateFileUnicode(inParentReference,tNewFileName.length,tNewFileName.unicode,0,NULL,&tNewFileReference,NULL); if (tErr!=noErr) { switch(tErr) { case bdNamErr: case fsmBadFFSNameErr: case errFSNameTooLong: // The file name is too long // Write the error logerror("File name is too long. The maximum length allowed is %ld characters\n",gMaxFileNameLength+2); break; case dskFulErr: logerror("Disk is full\n"); break; case errFSQuotaExceeded: logerror("Your quota are exceeded\n"); break; case dupFNErr: // The file already exists, we need to try to delete it before recreating it tErr=FSMakeFSRefUnicode(inParentReference,tNewFileName.length,tNewFileName.unicode,kTextEncodingDefaultFormat,&tNewFileReference); if (tErr==noErr) { // Delete the current ._file tErr=FSDeleteObject(&tNewFileReference); if (tErr==noErr) { goto tryagain; } else { // A COMPLETER } } else { // A COMPLETER } break; case afpVolLocked: // A COMPLETER break; default: // A COMPLETER break; } return -1; } tErr=FSOpenFork(&tNewFileReference,0,NULL,fsWrPerm,&tNewFileRefNum); if (tErr==noErr) { unsigned char tAppleDoubleMagicNumber[4]= {0x00,0x05,0x16,0x07}; unsigned char tAppleDoubleVersionNumber[4]={0x00,0x02,0x00,0x00}; unsigned char tAppleDoubleFiller[16]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; ByteCount tRequestCount; UInt16 tNumberOfEntries; UInt16 tSwappedNumberOfEntries; UInt32 tEntryID; UInt32 tEntryOffset; UInt32 tEntryLength; // Write the Magic Number tRequestCount=4; tErr=FSWriteFork(tNewFileRefNum,fsAtMark,0,tRequestCount,tAppleDoubleMagicNumber,NULL); if (tErr!=noErr) { goto writebail; } // Write the Version Number tRequestCount=4; tErr=FSWriteFork(tNewFileRefNum,fsAtMark,0,tRequestCount,tAppleDoubleVersionNumber,NULL); if (tErr!=noErr) { goto writebail; } // Write the Filler tRequestCount=16; tErr=FSWriteFork(tNewFileRefNum,fsAtMark,0,tRequestCount,tAppleDoubleFiller,NULL); if (tErr!=noErr) { goto writebail; } // Compute the Number of Entries tNumberOfEntries=0x0002; tSwappedNumberOfEntries=tNumberOfEntries; #ifdef __LITTLE_ENDIAN__ // Swap for Intel processor tSwappedNumberOfEntries=CFSwapInt16(tSwappedNumberOfEntries); #endif tRequestCount=2; tErr=FSWriteFork(tNewFileRefNum,fsAtMark,0,tRequestCount,&tSwappedNumberOfEntries,NULL); if (tErr!=noErr) { goto writebail; } // Write the Entries Descriptor // **** Finder Info tEntryID=0x00000009; // Finder Info ID tEntryOffset=0x0000001A+tNumberOfEntries*12; tEntryLength=0x00000020; // 32 bytes #ifdef __LITTLE_ENDIAN__ // Swap for Intel processor tEntryID=CFSwapInt32(tEntryID); tEntryOffset=CFSwapInt32(tEntryOffset); tEntryLength=CFSwapInt32(tEntryLength); #endif tRequestCount=4; tErr=FSWriteFork(tNewFileRefNum,fsAtMark,0,tRequestCount,&tEntryID,NULL); if (tErr!=noErr) { goto writebail; } tErr=FSWriteFork(tNewFileRefNum,fsAtMark,0,tRequestCount,&tEntryOffset,NULL); if (tErr!=noErr) { goto writebail; } tErr=FSWriteFork(tNewFileRefNum,fsAtMark,0,tRequestCount,&tEntryLength,NULL); if (tErr!=noErr) { goto writebail; } tEntryID=0x00000002; // Resource Fork ID tEntryOffset=0x00000052; if (hasResourceFork==TRUE) { // **** Finder Info tEntryLength=tResourceForkSize; // As you can see the AppleDouble format file is not ready for forks bigger than 2 GB } else { tEntryLength=0; } #ifdef __LITTLE_ENDIAN__ // Swap for Intel processor tEntryID=CFSwapInt32(tEntryID); tEntryOffset=CFSwapInt32(tEntryOffset); tEntryLength=CFSwapInt32(tEntryLength); #endif tRequestCount=4; tErr=FSWriteFork(tNewFileRefNum,fsAtMark,0,tRequestCount,&tEntryID,NULL); if (tErr!=noErr) { goto writebail; } tErr=FSWriteFork(tNewFileRefNum,fsAtMark,0,tRequestCount,&tEntryOffset,NULL); if (tErr!=noErr) { goto writebail; } tErr=FSWriteFork(tNewFileRefNum,fsAtMark,0,tRequestCount,&tEntryLength,NULL); if (tErr!=noErr) { goto writebail; } // Write the Entries // **** Write Finder Info #ifdef __LITTLE_ENDIAN__ // Intel Processors // Even though it's referenced as a bytes field in the File API, this is actually a structure we need to swap... if (inFileCatalogInfo->nodeFlags & kFSNodeIsDirectoryMask) { // It's a fragging folder FolderInfo * tFolderInfoStruct; ExtendedFolderInfo * tExtendedFolderInfoStruct; // Swap FolderInfo Structure tFolderInfoStruct=(FolderInfo *) inFileCatalogInfo->finderInfo; SWAP_RECT(tFolderInfoStruct->windowBounds); tFolderInfoStruct->finderFlags=CFSwapInt16(tFolderInfoStruct->finderFlags); SWAP_POINT(tFolderInfoStruct->location); tFolderInfoStruct->reservedField=CFSwapInt16(tFolderInfoStruct->reservedField); // Swap ExtendedFolderInfo Info Structure tExtendedFolderInfoStruct=(ExtendedFolderInfo *) inFileCatalogInfo->extFinderInfo; SWAP_POINT(tExtendedFolderInfoStruct->scrollPosition); tExtendedFolderInfoStruct->reserved1=CFSwapInt32(tExtendedFolderInfoStruct->reserved1); tExtendedFolderInfoStruct->extendedFinderFlags=CFSwapInt16(tExtendedFolderInfoStruct->extendedFinderFlags); tExtendedFolderInfoStruct->reserved2=CFSwapInt16(tExtendedFolderInfoStruct->reserved2); tExtendedFolderInfoStruct->putAwayFolderID=CFSwapInt32(tExtendedFolderInfoStruct->putAwayFolderID); } else { // I'm just a file, you know FileInfo * tFileInfoStruct; ExtendedFileInfo * tExtendedFileInfoStruct; // Swap FileInfo Structure tFileInfoStruct=(FileInfo *) inFileCatalogInfo->finderInfo; tFileInfoStruct->fileType=CFSwapInt32(tFileInfoStruct->fileType); tFileInfoStruct->fileCreator=CFSwapInt32(tFileInfoStruct->fileCreator); tFileInfoStruct->finderFlags=CFSwapInt16(tFileInfoStruct->finderFlags); SWAP_POINT(tFileInfoStruct->location); tFileInfoStruct->reservedField=CFSwapInt16(tFileInfoStruct->reservedField); // Swap ExtendedFileInfo Structure tExtendedFileInfoStruct=(ExtendedFileInfo *) inFileCatalogInfo->extFinderInfo; tExtendedFileInfoStruct->reserved1[0]=CFSwapInt16(tExtendedFileInfoStruct->reserved1[0]); tExtendedFileInfoStruct->reserved1[1]=CFSwapInt16(tExtendedFileInfoStruct->reserved1[1]); tExtendedFileInfoStruct->reserved1[2]=CFSwapInt16(tExtendedFileInfoStruct->reserved1[2]); tExtendedFileInfoStruct->reserved1[3]=CFSwapInt16(tExtendedFileInfoStruct->reserved1[3]); tExtendedFileInfoStruct->extendedFinderFlags=CFSwapInt16(tExtendedFileInfoStruct->extendedFinderFlags); tExtendedFileInfoStruct->reserved2=CFSwapInt16(tExtendedFileInfoStruct->reserved2); tExtendedFileInfoStruct->putAwayFolderID=CFSwapInt32(tExtendedFileInfoStruct->putAwayFolderID); } #endif tRequestCount=16; tErr=FSWriteFork(tNewFileRefNum,fsAtMark,0,tRequestCount,inFileCatalogInfo->finderInfo,NULL); if (tErr!=noErr) { goto writebail; } tErr=FSWriteFork(tNewFileRefNum,fsAtMark,0,tRequestCount,inFileCatalogInfo->extFinderInfo,NULL); if (tErr!=noErr) { goto writebail; } // **** Write Resource Fork? if (hasResourceFork==TRUE) { // We need to be clever and copy the Resource Fork by chunks to avoid using too much memory static UInt8 * tBuffer=NULL; static ByteCount tReadRequestCount=0; ByteCount tReadActualCount; OSErr tReadErr; #define GOLDIN_BUFFER_ONE_MEGABYTE_SIZE 1048576 if (tBuffer==NULL) { tReadRequestCount=GOLDIN_BUFFER_ONE_MEGABYTE_SIZE; do { tBuffer=(UInt8 *) malloc(tReadRequestCount*sizeof(UInt8)); tReadRequestCount/=2; } while (tBuffer==NULL && tReadRequestCount>1); if (tBuffer!=NULL && tReadRequestCount>1) { tReadRequestCount*=2; } else { // A COMPLETER } } do { tReadErr=FSReadFork(tForkRefNum, fsAtMark,0, tReadRequestCount, tBuffer, &tReadActualCount); if (tReadErr==noErr || tReadErr==eofErr) { tErr=FSWriteFork(tNewFileRefNum,fsAtMark,0,tReadActualCount,tBuffer,NULL); if (tErr!=noErr) { break; } } else { break; } } while (tReadErr!=eofErr); if (tReadErr!=eofErr) { // A problem occurred while reading the Resource Fork goto writebail; } else if (tErr!=noErr) { // A problem occurred while writing the Resource Fork Data to the AppleDouble file goto writebail; } } tErr=FSCloseFork(tNewFileRefNum); tErr=noErr; // Set the owner tErr=FSSetCatalogInfo(&tNewFileReference,kFSCatInfoPermissions,inFileCatalogInfo); if (tErr!=noErr) { //logerror("Permissions, owner and group could not be set for the AppleDouble file of %s\n",tPOSIXPath); tErr=-1; goto byebye; } } else { // A COMPLETER } // Close the Resource Fork if needed if (hasResourceFork==TRUE) { tErr=FSCloseFork(tForkRefNum); if (gStripResourceForks==TRUE && tErr==noErr) { // Strip the resource fork tErr=FSDeleteFork(inFileReference,sResourceForkName.length,sResourceForkName.unicode); if (tErr!=noErr) { switch(tErr) { case errFSForkNotFound: // This is not important tErr=noErr; break; default: // A COMPLETER break; } } } else { if (gStripResourceForks==TRUE && tErr!=noErr) { logerror("Resource Fork could not be stripped from %s\n",tPOSIXPath); // A COMPLETER } } } } return tErr; writebail: switch(tErr) { case dskFulErr: logerror("Disk is full\n"); break; case errFSQuotaExceeded: logerror("Your quota are exceeded\n"); break; default: logerror("An unknown error occurred while writing the AppleDouble file of %s\n",tPOSIXPath); break; } FSCloseFork(tNewFileRefNum); byebye: if (hasResourceFork==TRUE) { FSCloseFork(tForkRefNum); } return tErr; }
static OSErr mainQTInst(void *unused, OSType order, // Order to execute InstrData *InsHeader, // Ptr on instrument header sData **sample, // Ptr on samples data short *sampleID, // If you need to replace/add only a sample, not replace the entire instrument (by example for 'AIFF' sound) // If sampleID == -1 : add sample else replace selected sample. CFURLRef AlienFileURLRef, // IN/OUT file PPInfoPlug *thePPInfoPlug) { MADErr myErr = MADNoErr; FSIORefNum iFileRefI = -1; ByteCount inOutBytes; FSSpec tmpSpec; OSErr QTErr = noErr; myErr = CFURLToFSSpec(AlienFileURLRef, &tmpSpec); switch (myErr) { case memFullErr: return MADNeedMemory; break; default: case fnfErr: return order == MADPlugExport ? MADWritingErr : MADReadingErr; break; case noErr: break; } switch (order) { case MADPlugPlay: break; case MADPlugImport: { Ptr theSound; int lS, lE; short sS; unsigned long rate; bool stereo; FSSpec newFile; myErr = ConvertDataToWAVE(tmpSpec, &newFile, thePPInfoPlug); if (myErr == noErr) { theSound = ConvertWAV(&newFile, &lS, &lE, &sS, &rate, &stereo); if (theSound) { long sndSize = GetPtrSize(theSound); Ptr newSound = malloc(sndSize); memcpy(newSound, theSound, sndSize); DisposePtr(theSound); myErr = inAddSoundToMAD(newSound, sndSize, lS, lE, sS, 60, rate, stereo, newFile.name, InsHeader, sample, sampleID); } else { myErr = MADNeedMemory; } FSpDelete(&newFile); } } break; case MADPlugTest: { Boolean canOpenAsMovie = false; FInfo fInfo; FSpGetFInfo(&tmpSpec, &fInfo); QTErr = CanQuickTimeOpenFile(&tmpSpec, fInfo.fdType, 0, NULL, &canOpenAsMovie, NULL, 0); if (QTErr == noErr && canOpenAsMovie == true) { myErr = MADNoErr; } else { myErr = MADIncompatibleFile; } } break; case MADPlugExport: if (*sampleID >= 0) { OSType compType = 'NONE'; unsigned long rate; sData *curData = sample[*sampleID]; short numChan; FSpDelete(&tmpSpec); myErr = FSpCreate(&tmpSpec, 'TVOD', 'AIFF', smCurrentScript); if(myErr == noErr) myErr = FSpOpenDF(&tmpSpec, fsCurPerm, &iFileRefI); if (myErr == noErr) { inOutBytes = curData->size; rate = curData->c2spd; if (curData->stereo) numChan = 2; else numChan = 1; myErr = SetupAIFFHeader(iFileRefI, numChan, rate << 16L, curData->amp, compType, inOutBytes, 0); if(myErr == noErr) myErr = FSWriteFork(iFileRefI, fsAtMark, 0, inOutBytes, curData->data, &inOutBytes); FSCloseFork(iFileRefI); } } break; default: myErr = MADOrderNotImplemented; break; } return myErr; }
int ReadTOCData (FSVolumeRefNum theVolume, SDL_CD *theCD) { HFSUniStr255 dataForkName; OSStatus theErr; FSIORefNum forkRefNum; SInt64 forkSize; Ptr forkData = 0; ByteCount actualRead; CFDataRef dataRef = 0; CFPropertyListRef propertyListRef = 0; FSRefParam fsRefPB; FSRef tocPlistFSRef; FSRef rootRef; const char* error = "Unspecified Error"; const UniChar uniName[] = { '.','T','O','C','.','p','l','i','s','t' }; theErr = FSGetVolumeInfo(theVolume, 0, 0, kFSVolInfoNone, 0, 0, &rootRef); if(theErr != noErr) { error = "FSGetVolumeInfo"; goto bail; } SDL_memset(&fsRefPB, '\0', sizeof (fsRefPB)); fsRefPB.ref = &rootRef; fsRefPB.newRef = &tocPlistFSRef; fsRefPB.nameLength = sizeof (uniName) / sizeof (uniName[0]); fsRefPB.name = uniName; fsRefPB.textEncodingHint = kTextEncodingUnknown; theErr = PBMakeFSRefUnicodeSync (&fsRefPB); if(theErr != noErr) { error = "PBMakeFSRefUnicodeSync"; goto bail; } theErr = FSGetDataForkName (&dataForkName); if (theErr != noErr) { error = "FSGetDataForkName"; goto bail; } theErr = FSOpenFork (&tocPlistFSRef, dataForkName.length, dataForkName.unicode, fsRdPerm, &forkRefNum); if (theErr != noErr) { error = "FSOpenFork"; goto bail; } theErr = FSGetForkSize (forkRefNum, &forkSize); if (theErr != noErr) { error = "FSGetForkSize"; goto bail; } forkData = NewPtr (forkSize); if(forkData == NULL) { error = "NewPtr"; goto bail; } theErr = FSReadFork (forkRefNum, fsFromStart, 0 , forkSize, forkData, &actualRead); if(theErr != noErr) { error = "FSReadFork"; goto bail; } dataRef = CFDataCreate (kCFAllocatorDefault, (UInt8 *)forkData, forkSize); if(dataRef == 0) { error = "CFDataCreate"; goto bail; } propertyListRef = CFPropertyListCreateFromXMLData (kCFAllocatorDefault, dataRef, kCFPropertyListImmutable, NULL); if (propertyListRef == NULL) { error = "CFPropertyListCreateFromXMLData"; goto bail; } if(CFGetTypeID(propertyListRef)== CFDictionaryGetTypeID()) { CFDictionaryRef dictRef = (CFDictionaryRef)propertyListRef; CFDataRef theRawTOCDataRef; CFArrayRef theSessionArrayRef; CFIndex numSessions; CFIndex index; theRawTOCDataRef = (CFDataRef)CFDictionaryGetValue (dictRef, CFSTR(kRawTOCDataString)); theSessionArrayRef = (CFArrayRef)CFDictionaryGetValue (dictRef, CFSTR(kSessionsString)); numSessions = CFArrayGetCount (theSessionArrayRef); theCD->numtracks = 0; for(index = 0; index < numSessions; index++) { CFDictionaryRef theSessionDict; CFNumberRef leadoutBlock; CFArrayRef trackArray; CFIndex numTracks; CFIndex trackIndex; UInt32 value = 0; theSessionDict = (CFDictionaryRef) CFArrayGetValueAtIndex (theSessionArrayRef, index); leadoutBlock = (CFNumberRef) CFDictionaryGetValue (theSessionDict, CFSTR(kLeadoutBlockString)); trackArray = (CFArrayRef)CFDictionaryGetValue (theSessionDict, CFSTR(kTrackArrayString)); numTracks = CFArrayGetCount (trackArray); for(trackIndex = 0; trackIndex < numTracks; trackIndex++) { CFDictionaryRef theTrackDict; CFNumberRef trackNumber; CFNumberRef sessionNumber; CFNumberRef startBlock; CFBooleanRef isDataTrack; UInt32 value; theTrackDict = (CFDictionaryRef) CFArrayGetValueAtIndex (trackArray, trackIndex); trackNumber = (CFNumberRef) CFDictionaryGetValue (theTrackDict, CFSTR(kPointKeyString)); sessionNumber = (CFNumberRef) CFDictionaryGetValue (theTrackDict, CFSTR(kSessionNumberKeyString)); startBlock = (CFNumberRef) CFDictionaryGetValue (theTrackDict, CFSTR(kStartBlockKeyString)); isDataTrack = (CFBooleanRef) CFDictionaryGetValue (theTrackDict, CFSTR(kDataKeyString)); int idx = theCD->numtracks++; CFNumberGetValue (trackNumber, kCFNumberSInt32Type, &value); theCD->track[idx].id = value; CFNumberGetValue (startBlock, kCFNumberSInt32Type, &value); theCD->track[idx].offset = value; theCD->track[idx].type = (isDataTrack == kCFBooleanTrue) ? SDL_DATA_TRACK : SDL_AUDIO_TRACK; if (trackIndex > 0) { theCD->track[idx-1].length = theCD->track[idx].offset - theCD->track[idx-1].offset; } } CFNumberGetValue (leadoutBlock, kCFNumberSInt32Type, &value); theCD->track[theCD->numtracks-1].length = value - theCD->track[theCD->numtracks-1].offset; theCD->track[theCD->numtracks].offset = value; } } theErr = 0; goto cleanup; bail: SDL_SetError ("ReadTOCData: %s returned %d", error, theErr); theErr = -1; cleanup: if (propertyListRef != NULL) CFRelease(propertyListRef); if (dataRef != NULL) CFRelease(dataRef); if (forkData != NULL) DisposePtr(forkData); FSCloseFork (forkRefNum); return theErr; }