- int ret;
- WIMStruct *w;
- int write_flags = 0;
- size_t swm_name_len = strlen(swm_name);
- size_t swm_base_name_len;
- char name[swm_name_len + 20];
- char *swm_suffix;
-
- struct lookup_table_entry *lte_chain_head = NULL;
- struct lookup_table_entry *lte_chain_tail = NULL;
- long size_remaining = part_size;
- u64 total_bytes_written = 0;
- u64 total_bytes;
-
- ret = wimlib_open_wim(wimfile, flags, &w);
- if (ret != 0)
- return ret;
-
- total_bytes = wim_info_get_total_bytes(w->wim_info);
-
- if (flags & WIMLIB_OPEN_FLAG_CHECK_INTEGRITY)
- write_flags |= WIMLIB_WRITE_FLAG_CHECK_INTEGRITY;
- if (flags & WIMLIB_OPEN_FLAG_SHOW_PROGRESS)
- write_flags |= WIMLIB_WRITE_FLAG_SHOW_PROGRESS;
-
- w->hdr.flags |= WIM_HDR_FLAG_SPANNED;
- w->hdr.boot_idx = 0;
- randomize_byte_array(w->hdr.guid, WIM_GID_LEN);
- ret = begin_write(w, swm_name, write_flags);
- if (ret != 0)
- return ret;
-
- swm_suffix = strchr(swm_name, '.');
- memcpy(name, swm_name, swm_name_len + 1);
- if (swm_suffix) {
- swm_base_name_len = swm_suffix - swm_name;
- } else {
- swm_base_name_len = swm_name_len;
- name[sizeof(name) - 1] = '\0';
- swm_suffix = &name[sizeof(name) - 1];
+ struct swm_info *swm_info = _swm_info;
+ u64 stream_size;
+
+ stream_size = lte->resource_entry.size;
+
+ /* - Start first part if no parts have been started so far;
+ * - Start next part if adding this stream exceeds maximum part size,
+ * UNLESS the stream is metadata or if no streams at all have been
+ * added to the current part.
+ */
+ if (swm_info->num_parts == 0 ||
+ ((swm_info->parts[swm_info->num_parts - 1].size +
+ stream_size >= swm_info->max_part_size)
+ && !((lte->resource_entry.flags & WIM_RESHDR_FLAG_METADATA) ||
+ swm_info->parts[swm_info->num_parts - 1].size == 0)))
+ {
+ if (swm_info->num_parts == swm_info->num_alloc_parts) {
+ struct swm_part_info *parts;
+ size_t num_alloc_parts = swm_info->num_alloc_parts;
+
+ num_alloc_parts += 8;
+ parts = MALLOC(num_alloc_parts * sizeof(parts[0]));
+ if (!parts)
+ return WIMLIB_ERR_NOMEM;
+
+ for (unsigned i = 0; i < swm_info->num_parts; i++)
+ copy_part_info(&parts[i], &swm_info->parts[i]);
+
+ FREE(swm_info->parts);
+ swm_info->parts = parts;
+ swm_info->num_alloc_parts = num_alloc_parts;
+ }
+ swm_info->num_parts++;
+ INIT_LIST_HEAD(&swm_info->parts[swm_info->num_parts - 1].stream_list);
+ swm_info->parts[swm_info->num_parts - 1].size = 0;