Re: User friendly machine name (gestaltUserVisibleMachineName?) [SOLVED]
Re: User friendly machine name (gestaltUserVisibleMachineName?) [SOLVED]
- Subject: Re: User friendly machine name (gestaltUserVisibleMachineName?) [SOLVED]
- From: publiclook <email@hidden>
- Date: Mon, 2 Jun 2003 23:57:54 -0400
Using pointer arithmetic and obscure knowledge of the internal data
structure of a so called Pascal string is a poor practice IMHO. It is
not intention revealing. It will break if the string data is ever
acquired by another means. It relies on knowledge of a nearly dead
language, Pascal, while programming in C. It unnecessarily used pointer
arithmetic. It violated the paltry encapsulation of Apple's misguided
opaque data types.
How about using the following function provided just for this purpose ?
CFStringRef CFStringCreateWithPascalString (
CFAllocatorRef alloc,
ConstStr255Param pStr,
CFStringEncoding encoding
);
+(NSString * )machineName {
SInt32 gestaltReturnValue;
// Fetch machine name as pointer to PStr255 (Pascal String:
Byte0=length,Byte1..255=Characters)
if (!Gestalt(gestaltUserVisibleMachineName, &gestaltReturnValue)) {
return [(NSString
*)CFStringCreateWithPascalString(someAllocatorRef, gestaltReturnValue,
kCFStringEncodingMacRoman) autorelease];
} else {
return @"Unknown";
}
}
Hint: There is a serious question at the end of this post after
pointless expression of my humble and completely subjective opinion and
copious sample code!
Of course, like all aspects of Carbon, you have to know about wacky
poorly documented opaque types like CFAllocatorRef, ConstStr255Param,
and SInt32. Carbon and the Carbon influenced parts of Core Foundation
are the ugliest API I have ever seen (IMHO of course). This stuff
makes Win32 look elegant.
This Apple example prints the machine name using C and Carbon:
http://developer.apple.com/samplecode/Sample_Code/Overview/
MoreIsBetter/TestMoreOSUtils.c.htm
Then there is this lovely code sample from Apple that is not at all too
long for such a simple task:
static CFStringRef GetMachineNameAsCFString()
{
CFStringRef machineNameCF = NULL;
if ( RunningOnCarbonX() )
{
if ( RunningOnCarbonTenPointOneOrHigher() )
{
CSCopyMachineNameProc CSCopyMachineNameFunc;
CFBundleRef bundle = CFBundleGetBundleWithIdentifier( CFSTR(
"com.apple.Carbon" ) );
if ( bundle == NULL ) goto Bail;
CSCopyMachineNameFunc = (CSCopyMachineNameProc)
CFBundleGetFunctionPointerForName( bundle, CFSTR("CSCopyMachineName") );
if ( CSCopyMachineNameFunc != NULL )
machineNameCF = CSCopyMachineNameFunc();
}
else // A bug in Mac OS X 10.0 returns "localhost" rather than
the file sharing name
{ // For Mac OS X 10.0, the answer is to read the name directly
out of the System Configuration preferences file.
CFURLRef url;
CFDataRef data;
CFDictionaryRef dict;
CFDictionaryRef systemDict;
CFDictionaryRef system2Dict;
Boolean success;
url = CFURLCreateWithFileSystemPath( kCFAllocatorDefault,
CFSTR("/var/db/SystemConfiguration/preferences.xml"),
kCFURLPOSIXPathStyle, FALSE );
if ( url == NULL ) goto Bail;
success = CFURLCreateDataAndPropertiesFromResource(
kCFAllocatorDefault, url, &data, NULL, NULL, NULL );
if ( (success==true) && (data != NULL) )
{
dict = CFPropertyListCreateFromXMLData(
kCFAllocatorSystemDefault, data, kCFPropertyListImmutable, NULL );
if ( dict != NULL )
{
systemDict = CFDictionaryGetValue( dict, CFSTR("System") );
if ( systemDict != NULL )
{
system2Dict = CFDictionaryGetValue( systemDict, CFSTR("System") );
if ( system2Dict != NULL )
{
machineNameCF = CFDictionaryGetValue( system2Dict,
CFSTR("ComputerName") );
}
}
CFRelease( dict );
}
CFRelease( data );
}
CFRelease( url );
}
}
else // Running on Mac OS 8/9
{
#define kMachineNameID -16413
SInt16 saveResFile;
StringHandle stringH;
saveResFile = CurResFile(); // Save current resource file
UseResFile( kSystemResFile ); // Make system resource
current
stringH = GetString( kMachineNameID );
if ( stringH == NULL ) goto Bail;
machineNameCF = CFStringCreateWithPascalString(
kCFAllocatorSystemDefault, *stringH, kCFStringEncodingMacRoman );
UseResFile( saveResFile );
}
Bail:
return( machineNameCF );
}
Finally, is there some reason we don't like the NSHost class and +
currentHost and - (NSArray *)names or NSProcessInfo's - (NSString
*)hostName method ?
On Monday, June 2, 2003, at 11:08 PM, M. Uli Kusterer wrote:
At 21:00 Uhr +0200 02.06.2003, Rolf wrote:
+(NSString * )machineName {
SInt32 gestaltReturnValue;
// Fetch machine name as pointer to PStr255 (Pascal String:
Byte0=length, Byte1..255=Characters)
if (!Gestalt(gestaltUserVisibleMachineName, &gestaltReturnValue))
{
return [NSString stringWithCString: (char
*)gestaltReturnValue + 1];
} else {
return @"Unknown";
}
}
Rolf,
don't assume the string is terminated. It's a P-String, and if it's
been used for anything else by the OS before that, it might not
contain zero bytes beyond the machine name. Make that:
return [NSString stringWithCString: (char *)gestaltReturnValue + 1
length: ((char*)gestaltReturnValue[0])];
just to be on the safe side.
--
Cheers,
M. Uli Kusterer
------------------------------------------------------------
"The Witnesses of TeachText are everywhere..."
http://www.zathras.de
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.