void convert_to_caf_dictionary(const void *id3, size_t size, CFDictionaryPtr *odict) { CFDictionaryPtr idict; afutil::id3TagToDictinary(id3, size, &idict); CFIndex count = CFDictionaryGetCount(idict.get()); CFMutableDictionaryRef dictref = cautil::CreateDictionary(count); CFDictionaryPtr dictptr(dictref, CFRelease); struct dict_callback { static void f(const void *k, const void *v, void *c) { CFMutableDictionaryRef dp = static_cast<CFMutableDictionaryRef>(c); std::wstring wkey = cautil::CF2W(static_cast<CFStringRef>(k)); std::string skey = strutil::w2us(wkey); const char *cafname = get_cafname(skey.c_str()); if (cafname) { std::wstring wcafname = strutil::us2w(cafname); CFStringPtr cafkey = cautil::W2CF(wcafname); CFDictionarySetValue(dp, cafkey.get(), v); } } }; CFDictionaryApplyFunction(idict.get(), &dict_callback::f, dictref); odict->swap(dictptr); }
void fetchTags(AudioFileX &af, FILE *fp, std::map<std::string, std::string> *result) { std::map<std::string, std::string> tags; if (af.getFileFormat() == 'caff') { std::vector<uint8_t> data; af.getUserData('info', 0, &data); CAF::fetchTags(data, &tags); } else { CFDictionaryPtr dict; af.getInfoDictionary(&dict); if (dict.get()) CFDictionaryApplyFunction(dict.get(), fetchTagDictCallback, &tags); } TextBasedTag::normalizeTags(tags, result); }