// Given an application bundle reference and the name of an icon file // which is a resource in that bundle, look up the full (posix style) // path to that icon. Returns the path, or an empty wxString on failure wxString GetPathForIconFile( CFBundleRef bundle, CFStringRef iconFile ) { // If either parameter is NULL there is no hope of success if( !bundle || !iconFile ) return wxEmptyString; // Create a range object representing the whole string CFRange wholeString; wholeString.location = 0; wholeString.length = CFStringGetLength( iconFile ); // Index of the period in the file name for iconFile UniCharCount periodIndex; // In order to locate the period delimiting the extension, // iconFile must be represented as UniChar[] { // Allocate a buffer and copy in the iconFile string UniChar* buffer = new UniChar[ wholeString.length ]; CFStringGetCharacters( iconFile, wholeString, buffer ); // Locate the period character OSStatus status = LSGetExtensionInfo( wholeString.length, buffer, &periodIndex ); // Deallocate the buffer delete [] buffer; // If the period could not be located it will not be possible to get the URL if( status != noErr || periodIndex == kLSInvalidExtensionIndex ) return wxEmptyString; } // Range representing the name part of iconFile CFRange iconNameRange; iconNameRange.location = 0; iconNameRange.length = periodIndex - 1; // Range representing the extension part of iconFile CFRange iconExtRange; iconExtRange.location = periodIndex; iconExtRange.length = wholeString.length - periodIndex; // Get the name and extension strings wxCFStringRef iconName = CFStringCreateWithSubstring( kCFAllocatorDefault, iconFile, iconNameRange ); wxCFStringRef iconExt = CFStringCreateWithSubstring( kCFAllocatorDefault, iconFile, iconExtRange ); // Now it is possible to query the URL for the icon as a resource wxCFRef< CFURLRef > iconUrl = wxCFRef< CFURLRef >( CFBundleCopyResourceURL( bundle, iconName, iconExt, NULL ) ); if( !iconUrl.get() ) return wxEmptyString; // All being well, return the icon path return wxCFStringRef( CFURLCopyFileSystemPath( iconUrl, kCFURLPOSIXPathStyle ) ).AsString(); }
static PyObject *Launch_LSGetExtensionInfo(PyObject *_self, PyObject *_args) { PyObject *_res = NULL; OSStatus _err; UniChar *inNameLen__in__; UniCharCount inNameLen__len__; int inNameLen__in_len__; UniCharCount outExtStartIndex; if (!PyArg_ParseTuple(_args, "u#", &inNameLen__in__, &inNameLen__in_len__)) return NULL; inNameLen__len__ = inNameLen__in_len__; _err = LSGetExtensionInfo(inNameLen__len__, inNameLen__in__, &outExtStartIndex); if (_err != noErr) return PyMac_Error(_err); _res = Py_BuildValue("l", outExtStartIndex); return _res; }
CFStringRef HLFileSystemObject::CopyNameExtension() const { // get the file name from the catalog info HFSUniStr255 theUniStr255; OSStatus theError = FSGetCatalogInfo(&mFSRef, kFSCatInfoNone, NULL, &theUniStr255, NULL, NULL); ThrowIfError(theError, CAException(theError), "HLFileSystemObject::CopyNameExtension: couldn't get the catalog information"); // use Launch Services to find the start of the extension UniCharCount theExtensionStart = 0; LSGetExtensionInfo(theUniStr255.length, theUniStr255.unicode, &theExtensionStart); // assume that there wasn't an extension CFStringRef theExtension = NULL; if(theExtensionStart != kLSInvalidExtensionIndex) { // but there was, so make a CFString out of it theExtension = CFStringCreateWithCharacters(NULL, &theUniStr255.unicode[theExtensionStart], theUniStr255.length - theExtensionStart); } return theExtension; }
void HLFileSystemObject::SetNameExtension(CFStringRef inNameExtension) { // the FSRef for a file can change after renaming, // so don't allow it to be done while the file is open ThrowIf(IsOpenForReading() || IsOpenForWriting(), CAException(fBsyErr), "HLFileSystemObject::SetNameExtension: can't change the file name extension of an open file"); // make a raw unicode string out of the CFString containing the new extension CACFString theExtension(inNameExtension, false); UInt32 theExtensionLength = 255; UniChar theExtensionString[255]; theExtension.GetUnicodeString(theExtensionString, theExtensionLength); // get the file name from the catalog info HFSUniStr255 theNameString; OSStatus theError = FSGetCatalogInfo(&mFSRef, kFSCatInfoNone, NULL, &theNameString, NULL, NULL); ThrowIfError(theError, CAException(theError), "HLFileSystemObject::SetNameExtension: couldn't get the catalog information"); // use Launch Services to find the start of the extension UniCharCount theExtensionStart = 0; LSGetExtensionInfo(theNameString.length, theNameString.unicode, &theExtensionStart); UInt32 theCharsToCopy; if(theExtensionStart != kLSInvalidExtensionIndex) { // there already was an extension, so replace it // figure out how many characters worth of extension can fit theCharsToCopy = 255UL - theExtensionStart; // range it against the actual length of the extension theCharsToCopy = theExtensionLength < theCharsToCopy ? theExtensionLength : theCharsToCopy; // copy the extension memcpy(&theNameString.unicode[theExtensionStart], theExtensionString, theCharsToCopy * sizeof(UniChar)); // update the length of the name string theNameString.length = theExtensionStart + theCharsToCopy; // save off the current FSRef, since it may change FSRef theOldFSRef; memcpy(&theOldFSRef, &mFSRef, sizeof(FSRef)); // rename the file, getting us the new FSRef theError = FSRenameUnicode(&theOldFSRef, theNameString.length, theNameString.unicode, kTextEncodingUnknown, &mFSRef); ThrowIfError(theError, CAException(theError), "HLFileSystemObject::SetName: couldn't rename the file"); } else if(theNameString.length < 254) { // there isn't an extension yet, and there's room for at least two characters // make a raw unicode string with the period CFRange thePeriodRange = { 0, 1 }; UniChar thePeriodString[255]; CFStringGetCharacters(HLFileSystemCFStringConstants::sNameExtensionDelimiter, thePeriodRange, thePeriodString); // copy it at the end of the string theNameString.unicode[theNameString.length] = thePeriodString[0]; // update the length theNameString.length += 1; // figure out how many characters worth of extension can fit theCharsToCopy = 255UL - theNameString.length; // range it against the actual length of the extension theCharsToCopy = theExtensionLength < theCharsToCopy ? theExtensionLength : theCharsToCopy; // copy the extension memcpy(&theNameString.unicode[theNameString.length], theExtensionString, theCharsToCopy * sizeof(UniChar)); // update the length of the name string theNameString.length += theCharsToCopy; // save off the current FSRef, since it may change FSRef theOldFSRef; memcpy(&theOldFSRef, &mFSRef, sizeof(FSRef)); // rename the file, getting us the new FSRef theError = FSRenameUnicode(&theOldFSRef, theNameString.length, theNameString.unicode, kTextEncodingUnknown, &mFSRef); ThrowIfError(theError, CAException(theError), "HLFileSystemObject::SetName: couldn't rename the file"); } }