static void metadata_cache_update(FileData *fd, const gchar *key, const GList *values) { GList *work; work = fd->cached_metadata; while (work) { GList *entry = work->data; gchar *entry_key = entry->data; if (strcmp(entry_key, key) == 0) { /* key found - just replace values */ GList *old_values = entry->next; entry->next = NULL; old_values->prev = NULL; string_list_free(old_values); work->data = g_list_append(entry, string_list_copy(values)); DEBUG_1("updated %s %s\n", key, fd->path); return; } work = work->next; } /* key not found - prepend new entry */ fd->cached_metadata = g_list_prepend(fd->cached_metadata, g_list_prepend(string_list_copy(values), g_strdup(key))); DEBUG_1("added %s %s\n", key, fd->path); }
gboolean metadata_write_list(FileData *fd, const gchar *key, const GList *values) { if (!fd->modified_xmp) { fd->modified_xmp = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)string_list_free); } g_hash_table_insert(fd->modified_xmp, g_strdup(key), string_list_copy((GList *)values)); if (fd->exif) { exif_update_metadata(fd->exif, key, values); } metadata_write_queue_add(fd); file_data_increment_version(fd); file_data_send_notification(fd, NOTIFY_METADATA); if (options->metadata.sync_grouped_files && metadata_check_key(group_keys, key)) { GList *work = fd->sidecar_files; while (work) { FileData *sfd = work->data; work = work->next; if (filter_file_class(sfd->extension, FORMAT_CLASS_META)) continue; metadata_write_list(sfd, key, values); } } return TRUE; }
gboolean metadata_append_list(FileData *fd, const gchar *key, const GList *values) { GList *list = metadata_read_list(fd, key, METADATA_PLAIN); if (!list) { return metadata_write_list(fd, key, values); } else { gboolean ret; list = g_list_concat(list, string_list_copy(values)); list = remove_duplicate_strings_from_list(list); ret = metadata_write_list(fd, key, list); string_list_free(list); return ret; } }
GList *metadata_read_list(FileData *fd, const gchar *key, MetadataFormat format) { ExifData *exif; GList *list = NULL; if (!fd) return NULL; /* unwritten data overide everything */ if (fd->modified_xmp && format == METADATA_PLAIN) { list = g_hash_table_lookup(fd->modified_xmp, key); if (list) return string_list_copy(list); } /* Legacy metadata file is the primary source if it exists. Merging the lists does not make much sense, because the existence of legacy metadata file indicates that the other metadata sources are not writable and thus it would not be possible to delete the keywords that comes from the image file. */ if (strcmp(key, KEYWORD_KEY) == 0) { if (metadata_legacy_read(fd, &list, NULL)) return list; } else if (strcmp(key, COMMENT_KEY) == 0) { gchar *comment = NULL; if (metadata_legacy_read(fd, NULL, &comment)) return g_list_append(NULL, comment); } else if (strncmp(key, "file.", 5) == 0) { return g_list_append(NULL, metadata_file_info(fd, key, format)); } exif = exif_read_fd(fd); /* this is cached, thus inexpensive */ if (!exif) return NULL; list = exif_get_metadata(exif, key, format); exif_free_fd(fd, exif); return list; }