Ken and Robert, Thanks for your help. I know it must take a big chunk of your valuable time to write and test these examples. I really appreciate it. -Joe On Feb 18, 2008, at 10:38 AM, Ken Shmidheiser wrote: > > Robert, > > Thank you for your insights and thank you Joe for raising the > question. > > I have been in the process of converting my code base to FSRefs and > have written quite a few utilities (Robert: I am mostly finished > converting the FSp LongName File Utilities you wrote in 2005 to > FSRefs). > > Along the way, I have encountered an increasing number of UInt64s. > For instance, in Tlbx MoreFilesX.incl, alone, you find: > > In FSCatalogInfo: > dim dataLogicalSize as UInt64 // files only > dim dataPhysicalSize as UInt64 // files only > dim rsrcLogicalSize as UInt64 // files only > dim rsrcPhysicalSize as UInt64 // files only > > In FSVolumeInfo: > dim totalBytes as UInt64 // total number of bytes on volume > dim freeBytes as UInt64 // number of free bytes on volume > > In FSForkInfo: > dim currentPosition as UInt64 > dim logicalEOF as UInt64 > dim physicalEOF as UInt64 > dim process as UInt64// should be ProcessSerialNumber > > Until this morning, in the recursive folder iteration code below, I > had been reading the lo side of FB's UInt64 record kludge with some > success in getting the size of files as they are iterated through > this code in FB. However, it kept failing in FBtoC and I was > determined to try to fix it myself under the impression that UInt64s > were native to FBtoC. > > Adding your suggestions, the code no longer breaks in FBtoC. I look > forward to a permanent fix to this in FBtoC. And I hope if a new FB > Editor is ever developed, this will be on the list. > > FWIW, I wrote this code as a test bed for several FSRef file and > folder functions I've written. It uses Navigation Services and > FSRefs bypassing FB's Files$ function and FSSpecs completely to make > Herbie happy. > > Ken > > /* > > Recursive iteration > of folder contents > using FSRefs and > Navigation Services. > > Ken Shmidheiser > February 8, 2008 > > Modified with RP's UInt64 workarounds > February 18, 2008 > > */ > > include "Tlbx MoreFilesX.incl" > include "Tlbx Navigation.incl" > include "Tlbx LSinfo.incl" > > _typeFSRef = _"fsrf" > > #if ndef _FBtoC > local fn DoubleFromUInt64#( @u as ^UInt64 ) > '~'1 > dim as double tmp > tmp = u.lo > if ( u.lo < 0 ) then tmp += 4294967296.0 > if ( u.hi > 2097152 ) or ( u.hi < 0 )¬ > then stop "Loss of precision in DoubleFromUInt64#" > end fn = 4294967296.0*u.hi + tmp > #endif // ndef _FBtoC > > > // LS replacement for bulkier CFStringRef conversion - KS Feb. 13, > 2008 > local fn GetLongObjectNameFromFSRef$( objRef as ^FSRef ) as Str255 > '~'1 > dim as Str255 @ name > dim as CFStringRef @ displayName > dim as OSStatus err > dim as boolean result > > err = fn LSCopyDisplayNameForRef( #objRef, displayName ) > long if ( err == _noErr ) > result = fn CFStringGetPascalString( displayName,¬ > @name, SizeOf( name ), _kCFStringEncodingMacRoman ) > CFRelease( displayName ) > end if > > end fn = name > > > local fn DoSomethingWithThisObject( inCatInfo as ^FSCatalogInfo, > fsRef as ^FSRef ) > '~'1 > dim fInfo as ^FileInfo > dim as Double size > dim as OSType type, creator > dim as Str255 name, t, c > > long if( ( inCatInfo.nodeFlags and _kFSNodeIsDirectoryMask )¬ > == _kFSNodeIsDirectoryMask ) > > // It's a folder > > xelse > > // It's a file > name = fn GetLongObjectNameFromFSRef$( fsRef ) > > #if ndef _FbtoC > size = fn DoubleFromUInt64#( inCatInfo.dataPhysicalSize ) > #else > size = inCatInfo.dataPhysicalSize > #endif > > fInfo = @ inCatInfo.finderInfo > type = fInfo.fileType > creator = fInfo.fileCreator > > if type != 0 then t = mki$( type ) else t = "(NA)" > if creator != 0 then c = mki$( creator ) else c = "(NA)" > print t, c, using "####"; size / 1024; " KB ", name > > end if > > end fn > > > local mode > local fn IterateFolder( inFolder as ^FSRef ) as OSStatus > '~'1 > dim as OSStatus err > dim as FSIterator @ iterator > dim as ItemCount @ actualCount > dim as UInt32 i > dim as str255 n, s > > Xref catalogInfoArray(_maxInt) As FSCatalogInfo > Xref FSRefArray(_maxInt) As FSRef > > _kCatalogInfoBitmap = _kFSCatInfoNodeFlags¬ > _kFSCatInfoFinderInfo¬ > _kFSCatInfoDataSizes > > _kRequestCountPerIteration = ( (4096 * 4) / sizeof( FSCatalogInfo ) ) > > actualCount = 0 > err = fn FSOpenIterator( #inFolder, _kFSIterateFlat, iterator ) > if err then exit fn > > catalogInfoArray = fn malloc( SizeOf( FSCatalogInfo )¬ > * _kRequestCountPerIteration ) > FSRefArray = fn malloc( SizeOf( FSRef )¬ > * _kRequestCountPerIteration ) > > long if( catalogInfoArray == 0 ) > err = _memFullErr : exit fn > xelse > while ( err == _noErr ) > err = fn FSGetCatalogInfoBulk( iterator,¬ > _kRequestCountPerIteration,¬ > actualCount, #0,¬ > _kCatalogInfoBitmap,¬ > #catalogInfoArray,¬ > #FSRefArray, #0, #0 ) > > long if ( err == _noErr or err == _errFSNoMoreItems ) > for i = 0 to actualCount -1 > long if ( ( catalogInfoArray.nodeFlags(i)¬ > and _kFSNodeIsDirectoryMask ) == _kFSNodeIsDirectoryMask ) > // It's a folder > n = fn GetLongObjectNameFromFSRef$( FSRefArray( i ) ) > s = "•• Start of Subfolder: " + n + " ••" > print:print s > fn IterateFolder( FSRefArray( i ) ) > print "•• End of Subfolder " + n + " ••" > print > end if > // It's a file > fn DoSomethingWithThisObject( catalogInfoArray( i ), FSRefArray( i ) ) > next i > end if > wend > > fn free( catalogInfoArray ) > fn free( FSRefArray ) > > err = fn FSCloseIterator( iterator ) > > end if > > end fn = err > > > window 1 > > local fn SelectFolderFSRef( folderRef as ^FSRef ) as OSErr > '~'1 > dim as NavDialogCreationOptions navOptions > dim as NavDialogRef @ navRef > dim as NavReplyRecord @ navReply > dim as long @ count > dim as FSRef tempRef > dim as OSStatus err > > err = fn NavGetDefaultDialogCreationOptions( navOptions ) > long if ( err == _noErr ) > err = fn NavCreateChooseFolderDialog( navOptions,¬ > 0, 0, #0, navRef ) > long if ( err == _noErr ) > err = fn NavDialogRun( navRef ) > long if ( err == _noErr ) > err = fn NavDialogGetReply( navRef, navReply ) > long if ( err == _noErr ) > long if ( navReply.validRecord != _false ) > err = fn AECountItems( navReply.selection, count ) > long if ( count == 1 ) > err = fn AEGetNthPtr( navReply.selection, count,¬ > _typeFSRef, #0, #0, @tempRef, SizeOf( FSRef ), #0 ) > long if ( err = _noErr ) > BlockMove @tempRef, folderRef, sizeof( FSRef ) > end if > end if > end if > xelse > end // User canceled > end if > end if > end if > end if > > err = fn NavDisposeReply (navReply) > call NavDialogDispose ( navRef ) > > end fn = err > > > local fn DoScan > '~'1 > dim as OSStatus err > dim as FSRef @ folderRef > > err = fn SelectFolderFSRef( folderRef ) > long if( err == _noErr ) > cls > print:print "Click Cancel in Nav Dialog to exit" > print:print "Begin file iteration:" > print > print "TYPE", "CREATOR", "PHYSICAL SIZE", "NAME" > print "-----", "--------", "--------------", "-----" > err = fn IterateFolder( folderRef ) > xelse > end if > > end fn > > print "Click Cancel in Navigation Dialog to exit." > print > print "Choose folder to begin file iteration:" > > do > fn DoScan > HandleEvents > until gFBQuit > end > > -- > To unsubscribe, send ANY message to: futurebasic-unsubscribe@... >