bool OggSpeexMetadata::ReadMetadata(CFErrorRef *error) { // Start from scratch CFDictionaryRemoveAllValues(mMetadata); CFDictionaryRemoveAllValues(mChangedMetadata); UInt8 buf [PATH_MAX]; if(!CFURLGetFileSystemRepresentation(mURL, false, buf, PATH_MAX)) return false; // TODO: Use unique_ptr once the switch to C++11 STL is made std::auto_ptr<TagLib::FileStream> stream(new TagLib::FileStream(reinterpret_cast<const char *>(buf), true)); if(!stream->isOpen()) { if(error) { CFStringRef description = CFCopyLocalizedString(CFSTR("The file “%@” could not be opened for reading."), ""); CFStringRef failureReason = CFCopyLocalizedString(CFSTR("Input/output error"), ""); CFStringRef recoverySuggestion = CFCopyLocalizedString(CFSTR("The file may have been renamed, moved, deleted, or you may not have appropriate permissions."), ""); *error = CreateErrorForURL(AudioMetadataErrorDomain, AudioMetadataInputOutputError, description, mURL, failureReason, recoverySuggestion); CFRelease(description), description = nullptr; CFRelease(failureReason), failureReason = nullptr; CFRelease(recoverySuggestion), recoverySuggestion = nullptr; } return false; } TagLib::Ogg::Speex::File file(stream.get()); if(!file.isValid()) { if(nullptr != error) { CFStringRef description = CFCopyLocalizedString(CFSTR("The file “%@” is not a valid Ogg Speex file."), ""); CFStringRef failureReason = CFCopyLocalizedString(CFSTR("Not an Ogg Speex file"), ""); CFStringRef recoverySuggestion = CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), ""); *error = CreateErrorForURL(AudioMetadataErrorDomain, AudioMetadataInputOutputError, description, mURL, failureReason, recoverySuggestion); CFRelease(description), description = nullptr; CFRelease(failureReason), failureReason = nullptr; CFRelease(recoverySuggestion), recoverySuggestion = nullptr; } return false; } CFDictionarySetValue(mMetadata, kPropertiesFormatNameKey, CFSTR("Ogg Speex")); if(file.audioProperties()) AddAudioPropertiesToDictionary(mMetadata, file.audioProperties()); if(file.tag()) { std::vector<AttachedPicture *> pictures; AddXiphCommentToDictionary(mMetadata, pictures, file.tag()); for(auto picture : pictures) AddSavedPicture(picture); } return true; }
bool SFB::Audio::OggFLACMetadata::_ReadMetadata(CFErrorRef *error) { UInt8 buf [PATH_MAX]; if(!CFURLGetFileSystemRepresentation(mURL, false, buf, PATH_MAX)) return false; std::unique_ptr<TagLib::FileStream> stream(new TagLib::FileStream((const char *)buf, true)); if(!stream->isOpen()) { if(error) { SFB::CFString description = CFCopyLocalizedString(CFSTR("The file “%@” could not be opened for reading."), ""); SFB::CFString failureReason = CFCopyLocalizedString(CFSTR("Input/output error"), ""); SFB::CFString recoverySuggestion = CFCopyLocalizedString(CFSTR("The file may have been renamed, moved, deleted, or you may not have appropriate permissions."), ""); *error = CreateErrorForURL(Metadata::ErrorDomain, Metadata::InputOutputError, description, mURL, failureReason, recoverySuggestion); } return false; } TagLib::Ogg::FLAC::File file(stream.get()); if(!file.isValid()) { if(nullptr != error) { SFB::CFString description = CFCopyLocalizedString(CFSTR("The file “%@” is not a valid Ogg file."), ""); SFB::CFString failureReason = CFCopyLocalizedString(CFSTR("Not an Ogg file"), ""); SFB::CFString recoverySuggestion = CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), ""); *error = CreateErrorForURL(Metadata::ErrorDomain, Metadata::InputOutputError, description, mURL, failureReason, recoverySuggestion); } return false; } CFDictionarySetValue(mMetadata, kFormatNameKey, CFSTR("Ogg FLAC")); if(file.audioProperties()) { auto properties = file.audioProperties(); AddAudioPropertiesToDictionary(mMetadata, properties); if(properties->sampleWidth()) AddIntToDictionary(mMetadata, kBitsPerChannelKey, properties->sampleWidth()); } if(file.tag()) AddXiphCommentToDictionary(mMetadata, mPictures, file.tag()); return true; }
bool OggVorbisMetadata::ReadMetadata(CFErrorRef *error) { // Start from scratch CFDictionaryRemoveAllValues(mMetadata); CFDictionaryRemoveAllValues(mChangedMetadata); UInt8 buf [PATH_MAX]; if(!CFURLGetFileSystemRepresentation(mURL, false, buf, PATH_MAX)) return false; auto stream = new TagLib::FileStream(reinterpret_cast<const char *>(buf), true); TagLib::Ogg::Vorbis::File file(stream); if(!file.isValid()) { if(nullptr != error) { CFStringRef description = CFCopyLocalizedString(CFSTR("The file “%@” is not a valid Ogg Vorbis file."), ""); CFStringRef failureReason = CFCopyLocalizedString(CFSTR("Not an Ogg Vorbis file"), ""); CFStringRef recoverySuggestion = CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), ""); *error = CreateErrorForURL(AudioMetadataErrorDomain, AudioMetadataInputOutputError, description, mURL, failureReason, recoverySuggestion); CFRelease(description), description = nullptr; CFRelease(failureReason), failureReason = nullptr; CFRelease(recoverySuggestion), recoverySuggestion = nullptr; } return false; } CFDictionarySetValue(mMetadata, kPropertiesFormatNameKey, CFSTR("Ogg Vorbis")); if(file.audioProperties()) AddAudioPropertiesToDictionary(mMetadata, file.audioProperties()); if(file.tag()) { std::vector<AttachedPicture *> pictures; AddXiphCommentToDictionary(mMetadata, pictures, file.tag()); for(auto picture : pictures) AddSavedPicture(picture); } return true; }
bool FLACMetadata::ReadMetadata(CFErrorRef *error) { // Start from scratch CFDictionaryRemoveAllValues(mMetadata); CFDictionaryRemoveAllValues(mChangedMetadata); UInt8 buf [PATH_MAX]; if(!CFURLGetFileSystemRepresentation(mURL, false, buf, PATH_MAX)) return false; auto stream = new TagLib::FileStream(reinterpret_cast<const char *>(buf), true); TagLib::FLAC::File file(stream, TagLib::ID3v2::FrameFactory::instance()); if(!file.isValid()) { if(nullptr != error) { CFStringRef description = CFCopyLocalizedString(CFSTR("The file “%@” is not a valid FLAC file."), ""); CFStringRef failureReason = CFCopyLocalizedString(CFSTR("Not a FLAC file"), ""); CFStringRef recoverySuggestion = CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), ""); *error = CreateErrorForURL(AudioMetadataErrorDomain, AudioMetadataInputOutputError, description, mURL, failureReason, recoverySuggestion); CFRelease(description), description = nullptr; CFRelease(failureReason), failureReason = nullptr; CFRelease(recoverySuggestion), recoverySuggestion = nullptr; } return false; } CFDictionarySetValue(mMetadata, kPropertiesFormatNameKey, CFSTR("FLAC")); if(file.audioProperties()) { auto properties = file.audioProperties(); AddAudioPropertiesToDictionary(mMetadata, properties); if(properties->sampleWidth()) AddIntToDictionary(mMetadata, kPropertiesBitsPerChannelKey, properties->sampleWidth()); if(properties->sampleFrames()) AddLongLongToDictionary(mMetadata, kPropertiesTotalFramesKey, properties->sampleFrames()); } // Add all tags that are present if(file.ID3v1Tag()) AddID3v1TagToDictionary(mMetadata, file.ID3v1Tag()); if(file.ID3v2Tag()) { std::vector<AttachedPicture *> pictures; AddID3v2TagToDictionary(mMetadata, pictures, file.ID3v2Tag()); for(auto picture : pictures) AddSavedPicture(picture); } if(file.xiphComment()) { std::vector<AttachedPicture *> pictures; AddXiphCommentToDictionary(mMetadata, pictures, file.xiphComment()); for(auto picture : pictures) AddSavedPicture(picture); } // Add album art for(auto iter : file.pictureList()) { CFDataRef data = CFDataCreate(kCFAllocatorDefault, reinterpret_cast<const UInt8 *>(iter->data().data()), iter->data().size()); CFStringRef description = nullptr; if(!iter->description().isNull()) description = CFStringCreateWithCString(kCFAllocatorDefault, iter->description().toCString(true), kCFStringEncodingUTF8); AttachedPicture *picture = new AttachedPicture(data, static_cast<AttachedPicture::Type>(iter->type()), description); AddSavedPicture(picture); if(data) CFRelease(data), data = nullptr; if(description) CFRelease(description), description = nullptr; } return true; }
bool OggSpeexMetadata::ReadMetadata(CFErrorRef *error) { // Start from scratch CFDictionaryRemoveAllValues(mMetadata); CFDictionaryRemoveAllValues(mChangedMetadata); UInt8 buf [PATH_MAX]; if(!CFURLGetFileSystemRepresentation(mURL, false, buf, PATH_MAX)) return false; TagLib::IOStream *stream = new TagLib::FileStream(reinterpret_cast<const char *>(buf), true); TagLib::Ogg::Speex::File file(stream); if(!file.isValid()) { if(NULL != error) { CFMutableDictionaryRef errorDictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFStringRef displayName = CreateDisplayNameForURL(mURL); CFStringRef errorString = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFCopyLocalizedString(CFSTR("The file “%@” is not a valid Ogg Speex file."), ""), displayName); CFDictionarySetValue(errorDictionary, kCFErrorLocalizedDescriptionKey, errorString); CFDictionarySetValue(errorDictionary, kCFErrorLocalizedFailureReasonKey, CFCopyLocalizedString(CFSTR("Not an Ogg Speex file"), "")); CFDictionarySetValue(errorDictionary, kCFErrorLocalizedRecoverySuggestionKey, CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), "")); CFRelease(errorString), errorString = NULL; CFRelease(displayName), displayName = NULL; *error = CFErrorCreate(kCFAllocatorDefault, AudioMetadataErrorDomain, AudioMetadataInputOutputError, errorDictionary); CFRelease(errorDictionary), errorDictionary = NULL; } return false; } CFDictionarySetValue(mMetadata, kPropertiesFormatNameKey, CFSTR("Ogg Speex")); if(file.audioProperties()) AddAudioPropertiesToDictionary(mMetadata, file.audioProperties()); if(file.tag()) AddXiphCommentToDictionary(mMetadata, file.tag()); return true; }