Exemple #1
0
CFURLRef Caching_Stream::createFileURLWithPath(CFStringRef path)
{
    CFURLRef regularUrl = CFURLCreateWithString(kCFAllocatorDefault, path, NULL);
    
    CFURLRef fileUrl = CFURLCreateFilePathURL(kCFAllocatorDefault, regularUrl, NULL);
    
    CFRelease(regularUrl);
    
    return fileUrl;
}
CFURLRef Caching_Stream::createFileURLWithPath(CFStringRef path)
{
    CFURLRef fileUrl = NULL;
    
    if (!path) {
        return fileUrl;
    }
    
    CFStringRef escapedPath = CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, path, NULL, NULL, kCFStringEncodingUTF8);
    
    CFURLRef regularUrl = CFURLCreateWithString(kCFAllocatorDefault, (escapedPath ? escapedPath : path), NULL);
    
    if (regularUrl) {
        fileUrl = CFURLCreateFilePathURL(kCFAllocatorDefault, regularUrl, NULL);

        CFRelease(regularUrl);
    }
    
    if (escapedPath) {
        CFRelease(escapedPath);
    }
    
    return fileUrl;
}
Exemple #3
0
QString absolutePathFromOSX(const QString& s)
{
    QString result;
#if !(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1060)
    CFStringRef cfStr = CFStringCreateWithCString(kCFAllocatorDefault, s.toUtf8().constData(),  kCFStringEncodingUTF8);
    if (cfStr) {
        CFURLRef cfUrl = CFURLCreateWithString(kCFAllocatorDefault, cfStr, NULL);
        if (cfUrl) {
            CFErrorRef error = 0;
            CFURLRef cfUrlAbs = CFURLCreateFilePathURL(kCFAllocatorDefault, cfUrl, &error);
            if (cfUrlAbs) {
                CFStringRef cfStrAbsUrl = CFURLGetString(cfUrlAbs);
                result = fromCFString(cfStrAbsUrl);
                CFRelease(cfUrlAbs);
            }
            CFRelease(cfUrl);
        }
        CFRelease(cfStr);
    }
#else
    Q_UNUSED(s);
#endif
    return result;
}
AudioDecoder * AudioDecoder::CreateDecoderForInputSource(InputSource *inputSource, CFStringRef mimeType, CFErrorRef *error)
{
	if(nullptr == inputSource)
		return nullptr;

	AudioDecoder *decoder = nullptr;

	// Open the input source if it isn't already
	if(AutomaticallyOpenDecoders() && !inputSource->IsOpen() && !inputSource->Open(error))
		return nullptr;

	// As a factory this class has knowledge of its subclasses
	// It would be possible (and perhaps preferable) to switch to a generic
	// plugin interface at a later date

#if 0
	// If the input is an instance of HTTPInputSource, use the MIME type from the server
	// This code is disabled because most HTTP servers don't send the correct MIME types
	HTTPInputSource *httpInputSource = dynamic_cast<HTTPInputSource *>(inputSource);
	bool releaseMIMEType = false;
	if(!mimeType && httpInputSource && httpInputSource->IsOpen()) {
		mimeType = httpInputSource->CopyContentMIMEType();
		if(mimeType)
			releaseMIMEType = true;
	}
#endif

	// The MIME type takes precedence over the file extension
	if(mimeType) {
		if(FLACDecoder::HandlesMIMEType(mimeType)) {
			decoder = new FLACDecoder(inputSource);
			if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
				decoder->mInputSource = nullptr;
				delete decoder, decoder = nullptr;
			}
		}
		if(nullptr == decoder && WavPackDecoder::HandlesMIMEType(mimeType)) {
			decoder = new WavPackDecoder(inputSource);
			if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
				decoder->mInputSource = nullptr;
				delete decoder, decoder = nullptr;
			}
		}
		if(nullptr == decoder && MPEGDecoder::HandlesMIMEType(mimeType)) {
			decoder = new MPEGDecoder(inputSource);
			if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
				decoder->mInputSource = nullptr;
				delete decoder, decoder = nullptr;
			}
		}
		if(nullptr == decoder && OggVorbisDecoder::HandlesMIMEType(mimeType)) {
			decoder = new OggVorbisDecoder(inputSource);
			if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
				decoder->mInputSource = nullptr;
				delete decoder, decoder = nullptr;
			}
		}
		if(nullptr == decoder && OggSpeexDecoder::HandlesMIMEType(mimeType)) {
			decoder = new OggSpeexDecoder(inputSource);
			if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
				decoder->mInputSource = nullptr;
				delete decoder, decoder = nullptr;
			}
		}
#if !TARGET_OS_IPHONE
		if(nullptr == decoder && MusepackDecoder::HandlesMIMEType(mimeType)) {
			decoder = new MusepackDecoder(inputSource);
			if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
				decoder->mInputSource = nullptr;
				delete decoder, decoder = nullptr;
			}
		}
		if(nullptr == decoder && MonkeysAudioDecoder::HandlesMIMEType(mimeType)) {
			decoder = new MonkeysAudioDecoder(inputSource);
			if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
				decoder->mInputSource = nullptr;
				delete decoder, decoder = nullptr;
			}
		}
		if(nullptr == decoder && MODDecoder::HandlesMIMEType(mimeType)) {
			decoder = new MODDecoder(inputSource);
			if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
				decoder->mInputSource = nullptr;
				delete decoder, decoder = nullptr;
			}
		}
		if(nullptr == decoder && TrueAudioDecoder::HandlesMIMEType(mimeType)) {
			decoder = new TrueAudioDecoder(inputSource);
			if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
				decoder->mInputSource = nullptr;
				delete decoder, decoder = nullptr;
			}
		}
		if(nullptr == decoder && LibsndfileDecoder::HandlesMIMEType(mimeType)) {
			decoder = new LibsndfileDecoder(inputSource);
			if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
				decoder->mInputSource = nullptr;
				delete decoder, decoder = nullptr;
			}
		}
#endif
		if(nullptr == decoder && CoreAudioDecoder::HandlesMIMEType(mimeType)) {
			decoder = new CoreAudioDecoder(inputSource);
			if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
				decoder->mInputSource = nullptr;
				delete decoder, decoder = nullptr;
			}
		}

#if 0
		if(releaseMIMEType)
			CFRelease(mimeType), mimeType = nullptr;
#endif

		if(decoder)
			return decoder;
	}

	// If no MIME type was specified, use the extension-based resolvers

	CFURLRef inputURL = inputSource->GetURL();
	if(!inputURL)
		return nullptr;

	// Determining the extension isn't as simple as using CFURLCopyPathExtension (wouldn't that be nice?),
	// because although the behavior on Lion works like one would expect, on Snow Leopard it returns
	// a number that I believe is part of the inode number, but is definitely NOT the extension
	CFStringRef pathExtension = nullptr;
#if !TARGET_OS_IPHONE
	CFURLRef filePathURL = CFURLCreateFilePathURL(kCFAllocatorDefault, inputURL, nullptr);
	if(filePathURL) {
		pathExtension = CFURLCopyPathExtension(filePathURL);
		CFRelease(filePathURL), filePathURL = nullptr;
	}
	else
#endif
		pathExtension = CFURLCopyPathExtension(inputURL);

	if(!pathExtension) {
		if(error) {
			CFStringRef description = CFCopyLocalizedString(CFSTR("The type of the file “%@” could not be determined."), "");
			CFStringRef failureReason = CFCopyLocalizedString(CFSTR("Unknown file type"), "");
			CFStringRef recoverySuggestion = CFCopyLocalizedString(CFSTR("The file's extension may be missing or may not match the file's type."), "");
			
			*error = CreateErrorForURL(InputSourceErrorDomain, InputSourceFileNotFoundError, description, inputURL, failureReason, recoverySuggestion);
			
			CFRelease(description), description = nullptr;
			CFRelease(failureReason), failureReason = nullptr;
			CFRelease(recoverySuggestion), recoverySuggestion = nullptr;
		}

		return nullptr;
	}

	// TODO: Some extensions (.oga for example) support multiple audio codecs (Vorbis, FLAC, Speex)
	// and if openDecoder is false the wrong decoder type may be returned, since the file isn't analyzed
	// until Open() is called
	
	if(FLACDecoder::HandlesFilesWithExtension(pathExtension)) {
		decoder = new FLACDecoder(inputSource);
		if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
			decoder->mInputSource = nullptr;
			delete decoder, decoder = nullptr;
		}
	}
	if(nullptr == decoder && WavPackDecoder::HandlesFilesWithExtension(pathExtension)) {
		decoder = new WavPackDecoder(inputSource);
		if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
			decoder->mInputSource = nullptr;
			delete decoder, decoder = nullptr;
		}
	}
	if(nullptr == decoder && MPEGDecoder::HandlesFilesWithExtension(pathExtension)) {
		decoder = new MPEGDecoder(inputSource);
		if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
			decoder->mInputSource = nullptr;
			delete decoder, decoder = nullptr;
		}
	}
	if(nullptr == decoder && OggVorbisDecoder::HandlesFilesWithExtension(pathExtension)) {
		decoder = new OggVorbisDecoder(inputSource);
		if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
			decoder->mInputSource = nullptr;
			delete decoder, decoder = nullptr;
		}
	}
	if(nullptr == decoder && OggSpeexDecoder::HandlesFilesWithExtension(pathExtension)) {
		decoder = new OggSpeexDecoder(inputSource);
		if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
			decoder->mInputSource = nullptr;
			delete decoder, decoder = nullptr;
		}
	}
#if !TARGET_OS_IPHONE
	if(nullptr == decoder && MusepackDecoder::HandlesFilesWithExtension(pathExtension)) {
		decoder = new MusepackDecoder(inputSource);
		if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
			decoder->mInputSource = nullptr;
			delete decoder, decoder = nullptr;
		}
	}
	if(nullptr == decoder && MonkeysAudioDecoder::HandlesFilesWithExtension(pathExtension)) {
		decoder = new MonkeysAudioDecoder(inputSource);
		if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
			decoder->mInputSource = nullptr;
			delete decoder, decoder = nullptr;
		}
	}
	if(nullptr == decoder && MODDecoder::HandlesFilesWithExtension(pathExtension)) {
		decoder = new MODDecoder(inputSource);
		if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
			decoder->mInputSource = nullptr;
			delete decoder, decoder = nullptr;
		}
	}
	if(nullptr == decoder && TrueAudioDecoder::HandlesFilesWithExtension(pathExtension)) {
		decoder = new TrueAudioDecoder(inputSource);
		if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
			decoder->mInputSource = nullptr;
			delete decoder, decoder = nullptr;
		}
	}
	if(nullptr == decoder && LibsndfileDecoder::HandlesFilesWithExtension(pathExtension)) {
		decoder = new LibsndfileDecoder(inputSource);
		if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
			decoder->mInputSource = nullptr;
			delete decoder, decoder = nullptr;
		}
	}
#endif
	if(nullptr == decoder && CoreAudioDecoder::HandlesFilesWithExtension(pathExtension)) {
		decoder = new CoreAudioDecoder(inputSource);
		if(AutomaticallyOpenDecoders() && !decoder->Open(error)) {
			decoder->mInputSource = nullptr;
			delete decoder, decoder = nullptr;
		}
	}

	CFRelease(pathExtension), pathExtension = nullptr;

	return decoder;
}
Exemple #5
0
// Resolve a path and append it to the CLI settings structure
// The FSEvents API will, internally, resolve paths using a similar scheme.
// Performing this ahead of time makes things less confusing, IMHO.
static void append_path(const char* path)
{
#ifdef DEBUG
  fprintf(stderr, "\n");
  fprintf(stderr, "append_path called for: %s\n", path);
#endif

#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060

#ifdef DEBUG
  fprintf(stderr, "compiled against 10.6+, using CFURLCreateFileReferenceURL\n");
#endif

  CFURLRef url = CFURLCreateFromFileSystemRepresentation(NULL, (const UInt8*)path, (CFIndex)strlen(path), false);
  CFURLRef placeholder = CFURLCopyAbsoluteURL(url);
  CFRelease(url);

  CFMutableArrayRef imaginary = NULL;

  // if we don't have an existing url, spin until we get to a parent that
  // does exist, saving any imaginary components for appending back later
  while(!CFURLResourceIsReachable(placeholder, NULL)) {
#ifdef DEBUG
    fprintf(stderr, "path does not exist\n");
#endif

    CFStringRef child;

    if (imaginary == NULL) {
      imaginary = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
    }

    child = CFURLCopyLastPathComponent(placeholder);
    CFArrayInsertValueAtIndex(imaginary, 0, child);
    CFRelease(child);

    url = CFURLCreateCopyDeletingLastPathComponent(NULL, placeholder);
    CFRelease(placeholder);
    placeholder = url;

#ifdef DEBUG
    fprintf(stderr, "parent: ");
    CFShow(placeholder);
#endif
  }

#ifdef DEBUG
  fprintf(stderr, "path exists\n");
#endif

  // realpath() doesn't always return the correct case for a path, so this
  // is a funky workaround that converts a path into a (volId/inodeId) pair
  // and asks what the path should be for that. since it looks at the actual
  // inode instead of returning the same case passed in like realpath()
  // appears to do for HFS+, it should always be correct.
  url = CFURLCreateFileReferenceURL(NULL, placeholder, NULL);
  CFRelease(placeholder);
  placeholder = CFURLCreateFilePathURL(NULL, url, NULL);
  CFRelease(url);

#ifdef DEBUG
  fprintf(stderr, "path resolved to: ");
  CFShow(placeholder);
#endif

  // if we stripped off any imaginary path components, append them back on
  if (imaginary != NULL) {
    CFIndex count = CFArrayGetCount(imaginary);
    for (CFIndex i = 0; i<count; i++) {
      CFStringRef component = CFArrayGetValueAtIndex(imaginary, i);
#ifdef DEBUG
      fprintf(stderr, "appending component: ");
      CFShow(component);
#endif
      url = CFURLCreateCopyAppendingPathComponent(NULL, placeholder, component, false);
      CFRelease(placeholder);
      placeholder = url;
    }
    CFRelease(imaginary);
  }

#ifdef DEBUG
  fprintf(stderr, "result: ");
  CFShow(placeholder);
#endif

  CFStringRef cfPath = CFURLCopyFileSystemPath(placeholder, kCFURLPOSIXPathStyle);
  CFArrayAppendValue(config.paths, cfPath);
  CFRelease(cfPath);
  CFRelease(placeholder);

#else

#ifdef DEBUG
  fprintf(stderr, "compiled against 10.5, using realpath()\n");
#endif

  char fullPath[PATH_MAX + 1];

  if (realpath(path, fullPath) == NULL) {
#ifdef DEBUG
    fprintf(stderr, "  realpath not directly resolvable from path\n");
#endif

    if (path[0] != '/') {
#ifdef DEBUG
      fprintf(stderr, "  passed path is not absolute\n");
#endif
      size_t len;
      getcwd(fullPath, sizeof(fullPath));
#ifdef DEBUG
      fprintf(stderr, "  result of getcwd: %s\n", fullPath);
#endif
      len = strlen(fullPath);
      fullPath[len] = '/';
      strlcpy(&fullPath[len + 1], path, sizeof(fullPath) - (len + 1));
    } else {
#ifdef DEBUG
      fprintf(stderr, "  assuming path does not YET exist\n");
#endif
      strlcpy(fullPath, path, sizeof(fullPath));
    }
  }

#ifdef DEBUG
  fprintf(stderr, "  resolved path to: %s\n", fullPath);
  fprintf(stderr, "\n");
#endif

  CFStringRef pathRef = CFStringCreateWithCString(kCFAllocatorDefault,
                                                  fullPath,
                                                  kCFStringEncodingUTF8);
  CFArrayAppendValue(config.paths, pathRef);
  CFRelease(pathRef);

#endif
}