void extract_items()

in src/native/tools/extract/extract.cpp [131:219]


void extract_items(
	diffs::core::kitchen &kitchen,
	diffs::core::archive &archive,
	std::vector<diffs::core::item_definition> &items,
	fs::path target_path)
{
	std::map<diffs::core::item_definition, fs::path> item_paths;
	std::vector<diffs::core::item_definition> to_verify;

	kitchen.clear_requested_items();
	for (const auto &item : items)
	{
		if (!item.has_hash_for_alg(archive_diff::hashing::algorithm::sha256))
		{
			continue;
		}

		fs::path item_path;
		auto hashes = item.get_hashes();
		for (const auto &hash : hashes)
		{
			if (hash.first == archive_diff::hashing::algorithm::sha256)
			{
				auto item_path   = target_path / hash.second.get_data_string();
				item_paths[item] = item_path;
				break;
			}
		}

		if (fs::is_regular_file(item_path))
		{
			auto reader   = io::file::io_device::make_reader(item_path.string());
			auto new_item = diffs::core::create_definition_from_reader(reader);

			if (item.equals(new_item))
			{
				continue;
			}
		}

		kitchen.request_item(item);
	}

	if (!kitchen.process_requested_items())
	{
		printf("Failed to process requested items\n");
	}

	kitchen.resume_slicing();

	for (const auto &item : items)
	{
		if (!item_paths.contains(item))
		{
			continue;
		}

		auto prepared_item = kitchen.fetch_item(item);

		auto item_path                     = item_paths[item];
		std::shared_ptr<io::writer> writer = std::make_shared<io::file::binary_file_writer>(item_path.string());
		prepared_item->write(writer);
	}

	kitchen.cancel_slicing();

	for (const auto &item : items)
	{
		auto item_path = item_paths[item];
		auto reader    = io::file::io_device::make_reader(item_path.string());
		auto new_item  = diffs::core::create_definition_from_reader(reader);

		if (!item.equals(new_item))
		{
			printf(
				"Extracted item at %s is incorrect.\n\tExpected: %s\n\tActual: %s\n",
				item_path.string().c_str(),
				item.to_string().c_str(),
				new_item.to_string().c_str());
			auto deps = get_dependencies(archive, item);
			to_verify.insert(to_verify.end(), deps.begin(), deps.end());
		}
	}

	if (!to_verify.empty())
	{
		extract_items(kitchen, archive, to_verify, target_path);
	}
}