void cpio_file::regenerate_header_and_padding()

in src/native/archives/cpio_archives/cpio_file.cpp [161:220]


void cpio_file::regenerate_header_and_padding()
{
	switch (m_format)
	{
	case cpio_format::new_ascii:
	case cpio_format::newc_ascii: {
		auto header_data         = std::make_shared<std::vector<char>>();
		size_t total_header_size = NEW_ASCII_HEADER_SIZE;

		total_header_size += m_namesize;

		header_data->resize(total_header_size);

		struct
		{
			uint32_t *value;
			size_t offset;
			size_t length;
		} values[] = {
			{&m_ino, NEW_ASCII_HEADER_INO_OFFSET, NEW_ASCII_HEADER_INO_LENGTH},
			{&m_mode, NEW_ASCII_HEADER_MODE_OFFSET, NEW_ASCII_HEADER_MODE_LENGTH},
			{&m_uid, NEW_ASCII_HEADER_UID_OFFSET, NEW_ASCII_HEADER_UID_LENGTH},
			{&m_gid, NEW_ASCII_HEADER_GID_OFFSET, NEW_ASCII_HEADER_GID_LENGTH},
			{&m_nlink, NEW_ASCII_HEADER_NLINK_OFFSET, NEW_ASCII_HEADER_NLINK_LENGTH},
			{&m_mtime, NEW_ASCII_HEADER_MTIME_OFFSET, NEW_ASCII_HEADER_MTIME_LENGTH},
			{&m_filesize, NEW_ASCII_HEADER_FILESIZE_OFFSET, NEW_ASCII_HEADER_FILESIZE_LENGTH},
			{&m_dev_major, NEW_ASCII_HEADER_DEV_MAJOR_OFFSET, NEW_ASCII_HEADER_DEV_MAJOR_LENGTH},
			{&m_dev_minor, NEW_ASCII_HEADER_DEV_MINOR_OFFSET, NEW_ASCII_HEADER_DEV_MINOR_LENGTH},
			{&m_rdev_major, NEW_ASCII_HEADER_RDEV_MAJOR_OFFSET, NEW_ASCII_HEADER_RDEV_MAJOR_LENGTH},
			{&m_rdev_minor, NEW_ASCII_HEADER_RDEV_MINOR_OFFSET, NEW_ASCII_HEADER_RDEV_MINOR_LENGTH},
			{&m_namesize, NEW_ASCII_HEADER_NAMESIZE_OFFSET, NEW_ASCII_HEADER_NAMESIZE_LENGTH},
			{&m_check, NEW_ASCII_HEADER_CHECK_OFFSET, NEW_ASCII_HEADER_CHECK_LENGTH},
		};

		auto magic = (m_format == cpio_format::new_ascii) ? NEW_ASCII_MAGIC : NEWC_ASCII_MAGIC;

		memcpy(header_data->data(), magic, sizeof(NEWC_ASCII_MAGIC));

		for (const auto &value : values)
		{
			uint32_to_hexadecimal_characters(
				*value.value, std::span<char>{header_data->data() + value.offset, value.length});
		}

		memcpy(header_data->data() + NEW_ASCII_HEADER_SIZE, m_name.c_str(), m_name.size());

		m_header_reader =
			io::buffer::io_device::make_reader(header_data, io::buffer::io_device::size_kind::vector_size);

		auto header_padding_size = get_padding_needed(total_header_size, 4);
		m_header_padding_reader  = io::all_zeros_io_device::make_reader(header_padding_size);

		auto payload_padding_size = get_padding_needed(static_cast<size_t>(m_payload_reader.size()), 4);
		m_payload_padding_reader  = io::all_zeros_io_device::make_reader(payload_padding_size);
	}
	break;
	default:
		throw std::exception();
	}
}