+struct ads_entry *dentry_get_ads_entry(struct dentry *dentry,
+ const char *stream_name)
+{
+ size_t stream_name_len = strlen(stream_name);
+ if (!stream_name)
+ return NULL;
+ for (u16 i = 0; i < dentry->num_ads; i++)
+ if (ads_entry_has_name(&dentry->ads_entries[i],
+ stream_name, stream_name_len))
+ return &dentry->ads_entries[i];
+ return NULL;
+}
+
+static void ads_entry_init(struct ads_entry *ads_entry)
+{
+ memset(ads_entry, 0, sizeof(struct ads_entry));
+ INIT_LIST_HEAD(&ads_entry->lte_group_list.list);
+ ads_entry->lte_group_list.type = STREAM_TYPE_ADS;
+}
+
+/* Add an alternate stream entry to a dentry and return a pointer to it, or NULL
+ * on failure. */
+struct ads_entry *dentry_add_ads(struct dentry *dentry, const char *stream_name)
+{
+ u16 num_ads;
+ struct ads_entry *ads_entries;
+ struct ads_entry *new_entry;
+
+ if (dentry->num_ads == 0xffff)
+ return NULL;
+ num_ads = dentry->num_ads + 1;
+ ads_entries = REALLOC(dentry->ads_entries,
+ num_ads * sizeof(struct ads_entry));
+ if (!ads_entries)
+ return NULL;
+ if (ads_entries != dentry->ads_entries) {
+ /* We moved the ADS entries. Adjust the stream lists. */
+ for (u16 i = 0; i < dentry->num_ads; i++) {
+ struct list_head *cur = &ads_entries[i].lte_group_list.list;
+ cur->prev->next = cur;
+ cur->next->prev = cur;
+ }
+ }
+ dentry->ads_entries = ads_entries;
+
+ new_entry = &ads_entries[num_ads - 1];
+ if (change_ads_name(new_entry, stream_name) != 0)
+ return NULL;
+ dentry->num_ads = num_ads;
+ ads_entry_init(new_entry);
+ return new_entry;
+}
+
+void dentry_remove_ads(struct dentry *dentry, struct ads_entry *ads_entry)
+{
+ u16 idx;
+ u16 following;
+
+ wimlib_assert(dentry->num_ads);
+ idx = ads_entry - dentry->ads_entries;
+ wimlib_assert(idx < dentry->num_ads);
+ following = dentry->num_ads - idx - 1;
+
+ destroy_ads_entry(ads_entry);
+ memcpy(ads_entry, ads_entry + 1, following * sizeof(struct ads_entry));
+
+ /* We moved the ADS entries. Adjust the stream lists. */
+ for (u16 i = 0; i < following; i++) {
+ struct list_head *cur = &ads_entry[i].lte_group_list.list;
+ cur->prev->next = cur;
+ cur->next->prev = cur;
+ }
+
+ dentry->num_ads--;
+}
+