in src/native/archives/cpio_archives/cpio_file.cpp [262:346]
bool cpio_file::try_read_new_ascii_file_entry(const io::reader &reader)
{
char header[NEW_ASCII_HEADER_SIZE];
cpio_format format;
auto header_amount_read = reader.read_some(0, std::span<char>{header, sizeof(header)});
if (header_amount_read != sizeof(header))
{
return false;
}
if (0 == memcmp(header, NEW_ASCII_MAGIC, sizeof(NEW_ASCII_MAGIC)))
{
format = cpio_format::new_ascii;
}
else if (0 == memcmp(header, NEWC_ASCII_MAGIC, sizeof(NEWC_ASCII_MAGIC)))
{
format = cpio_format::newc_ascii;
}
else
{
return false;
}
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},
};
for (const auto &value : values)
{
*value.value = hexadecimal_characters_to_uint32(header, value.offset, value.length);
}
std::vector<char> name_buffer;
name_buffer.reserve(m_namesize);
if (reader.read_some(NEW_ASCII_HEADER_NAME_OFFSET, std::span<char>{name_buffer.data(), m_namesize}) != m_namesize)
{
return false;
}
m_name = string_from_nul_padded_string(std::string_view{name_buffer.data(), m_namesize});
size_t header_total_size = NEW_ASCII_HEADER_SIZE + m_namesize;
size_t header_padding_size = get_padding_needed(header_total_size, 4);
size_t file_data_start_offset = header_total_size + header_padding_size;
size_t file_data_end_offset = file_data_start_offset + m_filesize;
size_t payload_padding_size = get_padding_needed(file_data_end_offset, 4);
m_header_reader = reader.slice(0, header_total_size);
m_header_padding_reader = reader.slice(header_total_size, header_padding_size);
m_payload_reader = reader.slice(file_data_start_offset, m_filesize);
// if this is the end, just interpret the rest of the file as padding.
if (is_end_marker())
{
m_payload_padding_reader = reader.slice_at(file_data_end_offset);
}
else
{
m_payload_padding_reader = reader.slice(file_data_end_offset, payload_padding_size);
}
m_format = format;
return true;
}