[futurebasic] Re: [FB] CFArraySortValues() & CFArrayBSearchValues()

Message: < previous - next > : Reply : Subscribe : Cleanse
Home   : March 2010 : Group Archive : Group : All Groups

From: Bernie <fblist.bw@...>
Date: Sun, 21 Mar 2010 19:41:44 +0000
On 20 Mar 2010, at 20:17, Brian S wrote:

> Overview:
> 
> Current code uses an FB dynamic array of records. My goal is to incrementally change the code to CF so the code that accesses the record fields does not have to be changed. Array sorting and searching are required. Creating a mutable CFArray of CFMutableDictionaryRefs ( see: SortDescriptor example ) is a good technical solution but would require a switch away from FB records.
> 
> Detail, Discussion/Questions:
> 
> CFArraySortValues() and CFArrayBSearchValues() appear ideal but their operation is not clear to me given the use of an array of FB records ( really CFDataRefs loaded into a CFArray ). Both calls use a CFComparatorFunction (  and this type is used to cast the comparator function in C code ---i.e. (CFComparatorFunction)CFStringCompare  ) which appears to be a direct call to a standard CF call ( such as CFStringCompare() or others ). Since my code uses records, I need a user callback function ( which I believe the comparator can be ) to compare on specific record fields. The mechanics used for the comparator function with CFArraySortValues() should be the same for CFArrayBSearchValues(). I'm hoping someone has a working example of using at least CFArraySortValues().

I wonder if something like this will do what you want? Knocked together very quickly so I may have missed something.

'---------------
include "ConsoleWindow"

begin record MyInfo
dim as Str255 name
dim as long age
end record

begin enum
_kNameField
_kAgeField
end enum

local fn MySorter( val1 as CFDataRef, val2 as CFDataRef, context as pointer) as CFComparisonResult
'~'1
dim as MyInfo               info1, info2
dim as CFComparisonResult   result : result = _kCFCompareEqualTo
dim as long                 sortField : sortField = context

CFDataGetBytes( val1, fn CFRangeMake( 0, sizeof( MyInfo ) ), @info1 )
CFDataGetBytes( val2, fn CFRangeMake( 0, sizeof( MyInfo ) ), @info2 )
select ( sortField )
case _kNameField// name
if ( info1.name > info2.name ) then result = _kCFCompareGreaterThan
case _kAgeField// age
if ( info1.age > info2.age ) then result = _kCFCompareGreaterThan
end select
end fn = result

local fn PrintArray( array as CFMutableArrayRef )
'~'1
dim as CFDataRef   dataRef
dim as MyInfo      info
dim as CFIndex     count, index

count = fn CFArrayGetCount( array )
long if ( count )
for index = 0 to count - 1
dataRef = fn CFArrayGetValueAtIndex( array, index )
long if ( dataRef )
CFDataGetBytes( dataRef, fn CFRangeMake( 0, sizeof( MyInfo ) ), @info )
print info.name,info.age
end if
next index
end if
end fn

dim as CFMutableArrayRef   array
dim as CFDataRef           dataRef
dim as MyInfo              info

array = fn CFArrayCreateMutable( _kCFAllocatorDefault, 0, @kCFTypeArrayCallBacks )

info.name = "Robert"
info.age = 38
dataRef = fn CFDataCreate( _kCFAllocatorDefault, @info, sizeof( MyInfo ) )
CFArrayAppendValue( array, dataRef )
CFRelease( dataRef )

info.name = "Brian"
info.age = 43
dataRef = fn CFDataCreate( _kCFAllocatorDefault, @info, sizeof( MyInfo ) )
CFArrayAppendValue( array, dataRef )
CFRelease( dataRef )

info.name = "Michele"
info.age = 27
dataRef = fn CFDataCreate( _kCFAllocatorDefault, @info, sizeof( MyInfo ) )
CFArrayAppendValue( array, dataRef )
CFRelease( dataRef )


print "- unsorted -"
fn PrintArray( array )

print : print "- sort by name -"
CFArraySortValues( array, fn CFRangeMake( 0, fn CFArrayGetCount( array ) ), @fn MySorter, _kNameField )
fn PrintArray( array )

print : print "- sort by age -"
CFArraySortValues( array, fn CFRangeMake( 0, fn CFArrayGetCount( array ) ), @fn MySorter, _kAgeField )
fn PrintArray( array )


CFRelease( array )
'---------------

Bernie