[futurebasic] Re: [FB] CFString

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

From: Ken Shmidheiser <kshmidheiser@...>
Date: Sat, 19 Jan 2008 18:15:14 -0500
Max wrote:

> Mine does not have this FN even though the above info is the same.
> It is apparent that I do not have the latest version of the Header  
> Files as mine does not have many of the FN's used in your demo.


Humor me and download the new file so we're on the same page:


> It would also seem to me that with all the newbies coming on board  
> they might find something we take for granted just a little confusing.
> In the CFIndex file it is apparent to me that what is called  
> [indexID as CFIndex] is actually an 'arrayRef' or reference to some  
> array, where I have always thought of an index as an index to some  
> element into an array, like 5, 8, 13, 21, etc.
> It also seems to me that one should not only DIM some (pardon the  
> pun) arrayRef variable as some defined structure and maybe use  
> 'Ref' as in arrayRef to be a little clearer. I could not find any  
> definition [DEF] for 'CFIndex'.
> Also, should not one have to use some kind of FN such  
> as'CFIndexInit' then 'CFIndexCreate' prior to using 'CFIndexClear'  
> and proceeding to add elements to any new array? Like some form of  
> critical path or is all that taken care of in CFIndex.incl'.
> The above is not questioning your code but trying more to  
> understand the correct way to use this capability and also help to  
> steer newbies in the right direction without being obscure clearly.

Well, here's the mothership definition:

Core Foundation defines a number of miscellaneous symbols that are  
either used by many different opaque types, such as CFIndex, or apply  
to Core Foundation as a whole...

An integer type used throughout Core Foundation in several  
programmatic roles: as an array index and for count, size, and length  
parameters and return values.

typedef SInt32 CFIndex;

Core Foundation types as CFIndex all parameters and return values  
that might grow over time as the processor's address size changes. On  
architectures where pointer sizes are a different size (say, 64 bits)  
CFIndex might be declared to be also 64 bits, independent of the size  
of int. If you type your own variables that interact with Core  
Foundation as CFIndex, your code will have a higher degree of source  
compatibility in the future.


It's that expression "opaque types" the gets us.

Like me, you probably grew up driving a car with manual transmission.  
You really "felt" the car with a stick shift and, when daddy wasn't  
looking, could pop and ride the clutch to beat it to the next  
stoplight quicker than the guy in the Falcon. Nowadays hardly anybody  
drives a stick. Kids today have grown up "opaque" from the feel of  
the clutch and the ability to shift gears on command. The tradeoff is  
that going through the 28 traffic lights on the main drag in my town  
is a lot more convenient with an automatic than a stick which has a  
tendency to wear out the clutch leg. And now you can text message on  
the cell phone all day without worrying when to shift next.

CFIndex basically "opaques" or insulates us from the manual work of  
shifting arrays. We don't have to worry about bubble sorts, writing  
code to determine array size, inserting new elements and which is the  
"nth" element, etc. We call the accessor functions and let them do  
the work. There are even functions to write and read the array to  
disk. The CFIndex.incl opens with some comparisons between the old FB  
index$ way of doing things, and the new CFIndex way. It's short so  
here it is:


   Bernie Wylde,     24 October 2006

   CFINDEX                                                 FB index$

   CFIndex( indexID, element, string )                     index$ 
( element [, indexID] )
   string = CFIndex$( indexID, element )                   string =  
index$( element [, indexID] )
   CFIndexInsert( indexID, element, string )               index$ I 
( element [, indexID] ) = string
   CFIndexDelete( indexID, element )                       index$ D 
( element [, indexID] )
   CFIndexFind( indexID, startElement, string )            element =  
indexf( stringToFind [, startElement [, indexID]] )
   CFIndexGetCount( indexID )                              mem 
( _numElem [+ indexID] )
   CFIndexClear( indexID )                                 clear -1   
or  clear index$ [indexID]

   CFIndexAppend( indexID, string )                        -
   CFIndexSort( indexID )                                  -
   CFIndexSortRange( indexID, startElement, noOfElements ) -
   CFIndexWrite( indexID, fsSpec )                         -
   CFIndexRead(indexID, fsSpec )                           -


Concerning your question about initialization and creation of the  
array, again its all done automatically behind the scenes. No need to  
ride the clutch and shift. Take a look at fn CFIndex:

local mode
local fn CFIndex( indexID as CFIndex, element as CFIndex, @s as  
^Str255 )
dim as CFMutableArrayRef   array
dim as CFStringRef         string
dim as CFIndex             count

string = 0
array = fn CFIndexGetArray_priv( indexID )
long if ( array == 0 )
array = fn CFArrayCreateMutable( 0, 0, fn CFTypeArrayCallBacks )
fn CFIndexSetArray_priv( indexID, array )
end if
long if ( array )
count = fn CFArrayGetCount( array )
while ( count < element )
string = fn CFStringCreateWithPascalString( 0, "",  
_kCFStringEncodingMacRoman )
long if ( string )
CFArrayAppendValue( array, string )
CFRelease( string )
end if
string = fn CFStringCreateWithPascalString( 0, s.nil$,  
_kCFStringEncodingMacRoman )
long if ( string )
CFArraySetValueAtIndex( array, element, string )
CFRelease( string )
end if
end if
end fn

Notice in this function in CFIndex.incl that the array creation,  
initializing and indexing is all being done behind the scenes leaving  
the user the simple task of inputing data. I should point out that  
CFIndex.incl has several private functions that automatically handle  
all the housekeeping for us.

One other advantage is that CFIndex as part of CoreFoundation is  
optimized with the system so it's fast.

Also, let's make sure we're on the same page. Try the code with the  
file header attached as below and see if that makes a difference.

And a correction to my last post in this thread, this line

     dim as CFIndex shortDessertCFIndex, dessertCFIndex

should be replaced with this:

     dim as CFIndex shortDessertCFIndex, longDessertCFIndex


'                           Processor : cpuPPC
'                         Code Format : Carbon
'                             Runtime : Rntm Appearance.Incl
'                            Debugger : No
'                          CALL Req'd : No
'                    No Re-dim'd Vars : Yes
'                     dim'd Vars Only : Yes
'                        Debug Labels : Yes
'                           QB Labels : No
'                       Optimize STR# : Yes
'                 Ary Bounds Checking : Yes
'                       Show Warnings : Yes
'                       Register Vars : Yes
'               Make Line Start Table : No

include "CFIndex.incl"
include "Tlbx CFString.incl"

dim as CFIndex shortDessertCFIndex, longDessertCFIndex

shortDessertCFIndex = 0
longDessertCFIndex  = 1

fn CFIndexClear( shortDessertCFIndex )
fn CFIndex( shortDessertCFIndex, 0, "Apple pie"      )
fn CFIndex( shortDessertCFIndex, 1, "Cheese cake"    )
fn CFIndex( shortDessertCFIndex, 2, "Banana split"   )
fn CFIndex( shortDessertCFIndex, 3, "Fudge sundae"   )
fn CFIndex( shortDessertCFIndex, 4, "Chocolate cake" )
fn CFIndex( shortDessertCFIndex, 5, "Key lime pie"   )

fn CFIndexClear( longDessertCFIndex )
fn CFIndex( longDessertCFIndex, 0, "Apple pie with ice cream"          )
fn CFIndex( longDessertCFIndex, 1, "Cheese cake with cherries"         )
fn CFIndex( longDessertCFIndex, 2, "Banana split with pineapple"       )
fn CFIndex( longDessertCFIndex, 3, "Fudge sundae with whipped cream"   )
fn CFIndex( longDessertCFIndex, 4, "Chocolate cake with vanilla icing" )
fn CFIndex( longDessertCFIndex, 5, "Key lime pie with strawberries"    )

window 1,, (5, 45)-(400, 400)
dim as long i

print "Elements of shortDessertCFIndex:"

for i = 0 to fn CFIndexGetCount( shortDessertCFIndex ) -1
print "Element No."; i; " is: "; fn CFIndex$( shortDessertCFIndex, i )
next i

print "Elements of longDessertCFIndex:"

for i = 0 to fn CFIndexGetCount( longDessertCFIndex ) -1
print "Element No."; i; " is: "; fn CFIndex$( longDessertCFIndex, i )
next i

until gFBQuit