On Wed, 1 Nov 2000, Doug Simons wrote:

> Uli wrote (replying to Scott):
> > >The only other thing I thought of was to use a varargs-type parameter 
> > >list (i.e., pointer to an array with the number of elements passed as 
> > >a separate parameter) but instead of passing a null-terminated string, 
> > >you pass something like a pascal string except that the count would be 
> > >stored as a 4-byte integer instead of as single byte.  Saves a few 
> > >mallocs (which is always good), but does require some casting (which 
> > >isn't).
> >
> > Scott,
> >
> >  There's just one problem with this: Once we introduce UniCode or wide 
> > chars, we'll be royally screwed up with this. Or we'd have to add  
> a flag to
> > each such object telling whether it's Unicode or ASCII.
> >
> >  Since most hosts already have a built-in string object, maybe we could 
> > create an opaque object type instead (I have to admit, since Apple  
> began
> > using opaque types, I'm a real sucker for these critters).

I'd have to agree that they're a huge improvement over the rats-nest
of casting that has been the hallmark of MacOS programming up to this
point.  But they've definitely got disadvantages too, larger and
harder-to-read code being the most obvious.

> Anyway,  
> in that
> > case we'd have a pseudo-OO design that will be much more easily
> extendable.
> > Well, we'd define a data type that is the size of a memory address 
> > (pointer) as being a ParamStrRef. And then we provide callbacks
> (they're
> > not too costly these days, speed-wise, are they?) to create such
> an object,
> > to manipulate it etc.
> >
> >  ParamStrRef    CreateEmptyString();
> >  ParamStrRef    CreateStringFromCString( char* str );
> >  ParamStrRef    CreateStringFromText( unsigned long length, char*  
> txt );
> >
> >  void CopyCStringToString( ParamStrRef str, char* inStr );
> >  void CopyTextToString( ParamStrRef str, char* inStr,
> >                         unsigned long inLength );
> >
> >  void CopyStringToCString( ParamStrRef str, char* outStr,
> >                            unsigned long maxLength );
> >  void CopyStringToText( ParamStrRef str, char* outStr,
> >                         unsigned long *ioLength );
> >
> >  void ReleaseString( ParamStrRef str );
> >
> > Later when UniCode arrives we could extend these callbacks to
> create and
> > copy strings from/to Unicode strings, etc. And best of all, if the host 
> > internally uses Unicode, one would just have to make the ASCII-string 
> > callbacks convert from Unicode. This is so flexible that we could  
> even (if
> > we wanted) provide access to other data types besides strings,
> e.g. arrays,
> > or even longs, shorts, colors etc. although we might then change
> the name
> > from ParamStrRef to XCMDParamRef or something like that.
> >
> > >So who'd be responsible for deleting these beasties?
> >
> >  I guess it'd be best if we established a general rule. All
> strings are to
> > be released by the external, except those that need to exist befor  
> or after
> > the external call (i.e. parameters and result belong to the host). 

I think maybe the engine should do this instead.  That way it doesn't
have to copy data it needs to keep around when calling an external,
nor even when it gets data from the external that it can use and keep
unaltered.

> >  BTW -- "Text" is what I call a non-terminated string with a
> length long.
> > Choose any other name if it suits you better, this is just a draft  
> to help
> > where my English fails.
> >
> > Tsch�ss,
> > -- M. Uli Kusterer
> >
> 
> I think this is an excellent suggestion.  It's time to move beyond
> simple C structs and start embracing more robust object-oriented
> approaches.

Sounds like a good goal, as long as we can avoid the "quicksand" that
opaque structures can evolve into.  Ever done any AppleEvent
programming?  The only thing worse than the MacOS rats-nest of casting
is the ridiculous trial-and-error guesswork required to generate or
decompose an AEDesc.

> I think we should at least include numbers along with strings in our  
> list of supported data types.  While xTalk languages are essentially  
> typeless, allowing the user to treat all data as strings, internally  
> they all store numbers as numbers until a string representation is
> called for.  So it makes sense to allow externals to accept and
> provide numeric values directly to save some unnecessary conversions.

This could improve performance some, assuming you're passing numbers
around a lot.  But is this a common thing to do?

> I would suggest we begin the api with the simple types (say, strings  
> and doubles) before trying to tackle the more complex or
> implementation-specific ones like arrays and colors.

These are really the only types all the xTalks use internally
anyway...

> Let's make the reference generic, as Uli suggested, although I
> prefer XParamRef rather than XCMDParamRef (I've also changed "Text"  
> to "CharArray" as being hopefully more descriptive).  So, the api
> then starts to look something like this:
> 
> XParamRef    CreateEmptyParam();
> XParamRef    CreateParamWithCString( char* str );
> XParamRef    CreateParamWithCharArray( unsigned long length, char* txt ); 
> XParamRef    CreateParamWithDouble( double value );
> 
> void SetParamCStringValue( XParamRef param, char* inStr );
> void SetParamCharArrayValue( XParamRef param, char* inStr,
>                                        unsigned long inLength );
> void SetParamDoubleValue( XParamRef param, double value );
> 
> char* ParamCStringValue( XParamRef param );
> char* ParamCharArrayValue( XParamRef param, unsigned long *ioLength ); 
> double        ParamDoubleValue( XParamRef param );
> 
> void CopyParamCStringValue( XParamRef param, char** outStrPtr,
>                                 unsigned long *lengthPtr );
> void CopyParamCharArrayValue( XParamRef param, char** outStrPtr,
>                                      unsigned long * lengthPtr );
> 
> void ReleaseParam( XParamRef param );
> 
> The ParamCStringValue and ParamCharArrayValue calls would return
> pointers to strings in memory which would be valid until the external  
> returns but should not be altered by the external.  If the external  
> wants to keep the string until a later call or wants to alter the
> string, it must either copy the string itself, or use the "Copy..."  
> callback instead.
>
> Under this scheme, the external is only responsible for freeing the  
> memory if it received a copy of the string.   In the cases where a
> pointer is returned, it points to memory owned and managed by the
> opaque object.

How would it know?  And how would it know the type of the argument
that was passed to it?  And would conversion be automatic if you try
to "GetParamDoubleValue()" when the data was stored with
"SetParamCharArrayValue()"?
  Regards,
    Scott

> Regards,
> 
> Doug Simons
> Thoughtful Software
> 

********************************************************
Scott Raney  [EMAIL PROTECTED]  http://www.metacard.com
MetaCard: You know, there's an easier way to do that...

Reply via email to