[futurebasic] Re: [FB] FN UnsignedWideToDbl# crash

Message: < previous - next > : Reply : Subscribe : Cleanse
Home   : February 2008 : Group Archive : Group : All Groups

From: Joe Lertola <joefb@...>
Date: Tue, 19 Feb 2008 08:26:46 -0500
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@...
>